Flash attributes in Spring MVC 3.1 not visible to redirected JSP

6.1k Views Asked by At

I am using Spring 3.1's new Flash Attribute support to set flash attributes on a RedirectAttributes object in a Controller and then invoking a redirect. That redirect request is in turn caught by a filter which then sends it on its merry way to the JSP that it's intended for. The problem: I can't see the flash attributes either from within the filter's doFilter() method or from the JSP. Non-flash (URL) attributes make it just fine.

Controller that does the redirect:

@RequestMapping("/pages/login")
public String login (HttpServletRequest request, Map<String, Object> model, RedirectAttributes redirectAttributes) {
    model.put("userId", "batman");
    String redirectUrl = request.getParameter("redirectUrl");
    if (redirectUrl != null) {
        redirectAttributes.addAttribute("attr1","ababab");
        redirectAttributes.addFlashAttribute("flashAttr1", "flashflash");
        for (Iterator<String> iterator = model.keySet().iterator(); iterator.hasNext();) {
            String key = iterator.next();
            redirectAttributes.addFlashAttribute(key, model.get(key));
        }
        return "redirect:"+redirectUrl;
    } else {
        return "pages/login";
    }
}

The filter which picks up the redirect doesn't do anything interesting in this case:

public void doFilter (ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {
    HttpServletRequest httpRequest = (HttpServletRequest) request;
    //if (httpRequest.getSession().getAttribute("userId") == null) {
    //...do some stuff here which invokes controller above as well as the redirect
    //} else {
        chain.doFilter(request, response);
    //}
}

The page that gets redirected to following the filter:

...
<title>Test Web App 1</title>
</head>
<body>
<p>Flash attribute: <c:out value="${flashAttr1}"/></p>
<p>Welcome <c:out value="${userId}"/>!</p>
</body>
</html>

Neither flashAttr1 nor userId end up being populated in the page. The attr1 non-flash attribute the controller set does appear in the URL params of the page, so that seems to work.

Here is some output from log4j after I set springfamework.web to DEBUG:

19:15:44,406 DEBUG http-8080-1 view.ContentNegotiatingViewResolver:494 - Returni
ng redirect view [org.springframework.web.servlet.view.RedirectView: name 'redir
ect:http://my_hostname:8080/test-webapp-1/protected/protected_page.jsp';
URL [http://my_hostname:8080/test-webapp-1/protected/protected_page.jsp]]
19:15:44,406 DEBUG http-8080-1 servlet.DispatcherServlet:1155 - 
Rendering view [org.springframework.web.servlet.view.RedirectView: name
'redirect:http://my_hostname:8080/test-webapp-1/protected/protected_page.jsp';
URL [http://my_hostname:8080/test-webapp-1/protected/protected_page.jsp]] in
DispatcherServlet with name 'dispatcher'
19:15:44,421 DEBUG http-8080-1 support.DefaultFlashMapManager:199 - Saving Flash
Map=[Attributes={userId=batman, flashAttr1=flashflash}, targetRequestPath=/test-
webapp-1/protected/protected_page.jsp, targetRequestParams={attr1=[ababab]}]
19:15:44,421 DEBUG http-8080-1 servlet.DispatcherServlet:913 - Successfully comp
leted request

Following a brief stop at the filter I've shown above, I am taken to the page with URL

http://my_hostname:8080/test-webapp-1/protected/protected_page.jsp?attr1=ababab

But neither of the attributes I expect that JSP to find are displayed. I have also debugged through the doFilter() method shown above and failed to find the flash attributes in the request's session.

I'm not sure exactly what's wrong at this point. Everything works as expected except for those flash attributes. If there is anything else I should provide to make the situation more clear, I will be happy to.

1

There are 1 best solutions below

0
On

Ran into this issue a few months ago with AJAX-related redirects. If you use a read-only HTTP POST pattern, you can specify a @ResponseStatus to simulate a POST. Also be sure to have your method return a View or ModelAndView (as opposed to String) so that Spring knows to look up the Flash scope for the given @RequestMapping.

Pseudocode:

@RequestMapping(...)
@ResponseStatus(OK)
public ModelAndView login (...) {
    ...
}