29

My controller method is returning a ModelAndView, but there is also a requirement to write a cookie back to client. Is it possible to do it in Spring? Thanks.

Bastian Voigt
  • 5,034
  • 6
  • 42
  • 62
Bobo
  • 8,217
  • 17
  • 62
  • 85

4 Answers4

54

If you add the response as parameter to your handler method (see flexible signatures of @RequestMapping annotated methods – same section for 3.2.x, 4.0.x, 4.1.x, 4.3.x, 5.x.x), you may add the cookie to the response directly:

Kotlin

@RequestMapping(["/example"])
fun exampleHandler(response: HttpServletResponse): ModelAndView {
   response.addCookie(Cookie("COOKIENAME", "The cookie's value"))
   return ModelAndView("viewname")
}

Java

@RequestMapping("/example")
private ModelAndView exampleHandler(HttpServletResponse response) {

        response.addCookie(new Cookie("COOKIENAME", "The cookie's value"));

        return new ModelAndView("viewname");
}
Wolfram
  • 7,989
  • 3
  • 43
  • 64
10

Not as part of the ModelAndView, no, but you can add the cookie directly to the HttpServletResponse object that's passed in to your controller method.

skaffman
  • 390,936
  • 96
  • 800
  • 764
8

You can write a HandlerInterceptor that will take all Cookie instances from your model and generate the appropriate cookie headers. This way you can keep your controllers clean and free from HttpServletResponse.

@Component
public class ModelCookieInterceptor extends HandlerInterceptorAdapter {

    @Override
    public void postHandle(HttpServletRequest req, HttpServletResponse res, Object handler, ModelAndView modelAndView) throws Exception {
        if (modelAndView != null) {
            for (Object value : modelAndView.getModel().values()) {
                if (value instanceof Cookie)
                    res.addCookie((Cookie) value);
            }
        }
    }

}

NB . Don't forget to register the interceptor either with <mvc:interceptors> (XML config) or WebMvcConfigurer.addInterceptors() (Java config).

rustyx
  • 73,455
  • 21
  • 176
  • 240
  • 1
    This is especially useful if you want to configure whether to return the data as a Cookie, Header, JSON, etc. and provides good separation of concerns. – kuporific Jul 25 '14 at 17:29
  • This doesn't seems to work, We probably need a ControllerAdvice https://www.programmersought.com/article/57186340561/ – Monk789 Jun 08 '21 at 09:17
-1

RustyX's solution in Java 8:

@Component
    public class ModelCookieInterceptor extends HandlerInterceptorAdapter {

        @Override
        public void postHandle(HttpServletRequest req, HttpServletResponse res, Object handler, ModelAndView modelAndView) throws Exception{
            if (modelAndView != null) {
                modelAndView.getModel().values().stream()
                    .filter(c -> c instanceof Cookie)
                    .map(c -> (Cookie) c)
                    .forEach(res::addCookie);
            }
        }
    }
mto23
  • 9
  • 3