如何在Spring MVC中的Post / Redirect / Get模式的请求之间传递数据?

13

我有一个表单,使用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;
 } 
为了解决双重提交问题,我正在使用GET请求将重定向指向相同的映射路由。
 @RequestMapping(value="/signin.html",method = RequestMethod.GET)
 public ModelAndView submitPRG(){
     ModelAndView mv = new ModelAndView("submitted");
     mv.addObject("message", "Submitted Correctly");
     return mv;
 }

我这样解决了双重提交的问题。

我有几个问题:

1)怎样才能知道 /signin.html 上的 GET 请求是来自重定向而不是用户在浏览器中请求的呢?我只想关闭用户浏览 http://server/signin.html 并获取 "已成功提交" 信息的选项。 我知道我可以添加类似 /signin.html?submitted=true 的东西,但我想让它更加清晰。

2)有没有办法从 submit()ModelAndView 对象传递给 submitPRG()

或者说,在这种情况下还有其他使用 PRG 的方法吗?

2个回答

17
您想要的行为被称为“闪存作用域”。通常通过将要在重定向后显示的消息存储在会话中实现。 Spring团队承诺在Spring 3.1(SPR-6464)中实现它。同时,您可以查看mvc-showcase示例中的闪存作用域实现,这很容易,所以您可以自己做。另一种方法是将所需数据作为重定向URL的参数添加。请注意,如果提交方法保存了模型对象,以便稍后可以通过某个标识符访问它,则有意义将重定向到显示该对象的页面(即/users.html?userId=...而不是 /signin.html),并从闪存作用域在该页面上显示“已正确提交”的消息。因此,闪存作用域通常用于传递消息,而不是模型对象。

2
需要小心使用Flash,因为它的时间一致性不能完全保证。来自Spring文档:http://static.springsource.org/spring/docs/3.2.x/spring-framework-reference/html/mvc.html#mvc-flash-attributes 这可能不是问题,但至少需要注意。 - sanimalp

4
如何知道 /signin.html 上的 GET 请求是来自重定向而非浏览器中用户请求的?
您可以在会话中存储一个标记,也可以查看 HTTP 标头中的引用者。我建议使用基于会话的消息传递机制来实现"提交正确"的消息提示。有时这被称为 "flash",StackExchange 经常使用它们(显示在屏幕顶部的消息)。
感谢您的提问,但是如何从 HttpServletRequest 中获取引用者呢?
HttpServletRequest.getHeader("Referer")

1
谢谢您的提问,但是我该如何从HttpServletRequest中获取引荐者信息? - danny.lesnik

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接