Question

I am handling forms in Spring MVC and I submitted a form and I am trying to redirect the post request to avoid resubmitting the form with refresh button.

But I need a dynamically generated value to be displayed based on the form submission in the redirected page. So I am saving that value in session in the post handler method and getting it back in the redirected page handling method.

Would I get the session attribute shown displayed in the redirected page like request parameters in GET method case?

Following is the code that I am using:

This method is handling the form submission

@RequestMapping(value="/something", method=RequestMethod.POST) 
public String testStopped(Model model, WebRequest request, HttpSession session) {
    //...
    int foo = 1234;//some dynamically generated value
    session.setAttribute("foo", foo);
    return "redirect:/something/somethingelse";
}

This method is handling the redirected page

@RequestMapping(value="/something/somethingelse") 
public String testStopped(Model model, HttpSession session) {
    ...
    Integer kungfoo = (Integer) session.getAttribute("foo");
    model.addAttribute("kungfoo", kungfoo);
    return "somethingelse";
}

This is the url I end up with after redirect: http://wikedlynotsmart.com/something/somethingelse?kungfoo=1234

Is there a way to for ?kungfoo=1234 not to be displayed at the end and still get it passed to the redirect request handler method?

Is this how it is supposed to work or I am committing a blunder somewhere? Could someone help me understand it?

Thanks.

Was it helpful?

Solution

Quote from the documentation:

By default all model attributes are considered to be exposed as URI template variables in the redirect URL. Of the remaining attributes those that are primitive types or collections/arrays of primitive types are automatically appended as query parameters.

This means that kungfoo is an attribute of your model in the first method, and that it's thus automatically added as a request param to the redirect URL.

The rest of the paragraph explains how to proceed if you don't want all the attributes in the redirect URL (although I have the feeling that the default is exactly what you should use, in this case, since you want the second request to get back the kungfoo value):

In annotated controllers however the model may contain additional attributes originally added for rendering purposes (e.g. drop-down field values). To gain precise control over the attributes used in a redirect scenario, an @RequestMapping method can declare an argument of type RedirectAttributes and use it to add attributes for use in RedirectView. If the controller method does redirect, the content of RedirectAttributes is used. Otherwise the content of the default Model is used.

If you want to stay with this solution of storing the value in the session, you should use a flash attribute, so it's removed from the session as soon as the second request is received. The rest of the paragraph explains how to use them.

OTHER TIPS

Here is what worked for me:

Adding an argument of type RedirectAttributes and adding foo as a flash attribute to it.

This method is handling the form submission

@RequestMapping(value="/something", method=RequestMethod.POST) 
public String testStopped(Model model, WebRequest request, RedirectAttributes redirectAttributes) {
    //...
    int foo = 1234;
    redirectAttributes.addFlashAttribute("foo", foo);
    return "redirect:/something/somethingelse";
}

This method is handling the redirected page; nothing needs to be done here for "foo"

@RequestMapping(value="/something/somethingelse") 
public String testStopped() {
    return "somethingelse";
}

This is how you use "foo" in somethingelse.jsp

${foo}

And http://wikedlynotsmart.com/somethingelse is what I get in the URL.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top