Question

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.

Was it helpful?

Solution

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.0.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");
}

OTHER TIPS

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.

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'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);
            }
        }
    }
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top