How to pass data between requests of Post/Redirect/Get pattern in Spring MVC?

danny.lesnik picture danny.lesnik · Mar 8, 2011 · Viewed 16.2k times · Source

I have a form which submits user first and last name using POST signin.html

 @RequestMapping(value="/signin.html",method = RequestMethod.POST)
 public ModelAndView submit(@Valid User user){
    ModelAndView mv = new ModelAndView("redirect:signin.html"); 
    //Business logic with user account
    return mv;
 } 

In order to solve double submit problem I'm redirecting to the same mapping using GET request.

 @RequestMapping(value="/signin.html",method = RequestMethod.GET)
 public ModelAndView submitPRG(){
     ModelAndView mv = new ModelAndView("submitted");
     mv.addObject("message", "Submitted Correctly");
     return mv;
 }

This way I solve double submit problem.

I have few questions:

1) How can I know that GET request on /signin.html coming from redirect and was not requested by user in browser? I just would like to close option for user to browse http://server/signin.html and to get "Submitted Correctly" message. I know that I can add something like /signin.html?submitted=true but I would like to make it more clean.

2) is there any way to pass ModelAndView object from submit() to submitPRG()?

Or simply is there any other way to use PRG in this case?

Answer

axtavt picture axtavt · Mar 8, 2011

The behaviour you want is called "flash scope". It's usually implemented by storing message to be displayed after redirect in the session.

Spring team promises to implement it in Spring 3.1 (SPR-6464). Meanwhile you can take a look at the implementation of flash scope in mvc-showcase sample, it's pretty easy, so you can do it yourself.

Alternative approach is to add required data as parameters to redirect URL. Note that if your submit method saves model object so that it can be later accessed by some identifier, it makes sense to redirect to the page that displays that object (i.e. /users.html?userId=... instead of /signin.html), and display the "Submitted Correctly" message on that page from the flash scope.

So, flash scope is usually used to pass messages, not model objects.