2016-03-22 49 views
8

我有一个Spring-mvc应用程序,并且在每个控制器中,我向SessionAttributes添加一个表单以在保存,删除或执行另一个获取请求时保留属性。当我尝试在另一个浏览器选项卡中打开某个链接并尝试提交第一个链接时,主要问题就变成了。我尝试this解决方案,但当我做一个重定向(在控制器中,我只有1个返回视图,其他方法做重定向)它创建一个新的对话,并找不到以前的一个。SessionAttributes打开新的浏览器标签时

我还有一个关于这个triying使用春季会议的问题,这是here,但我不知道这是否也能起作用。

回答

5

你看过Spring的RedirectAttributes吗?我自己并没有使用它,但它听起来像它应该做你想做的事情。 RedirectAttributes通常用于GET /重定向/ POST模式,并且at least one user似乎认为以这种方式传递会话属性是不好的做法,但是他们继续提到似乎没有更好的解决方案。总之,在文档中所示的例子:

@RequestMapping(value = "/accounts", method = RequestMethod.POST) 
public String handle(Account account, BindingResult result, RedirectAttributes redirectAttrs) { 
    if (result.hasErrors()) { 
     return "accounts/new"; 
    } 
    // Save account ... 
    redirectAttrs.addAttribute("id", account.getId()).addFlashAttribute("message", "Account created!"); 
    return "redirect:/accounts/{id}"; 
} 

将添加“消息”属性的RedirectModel,如果你的控制器重定向,那么无论方法处理重定向可以访问像这样的数据:

@RequestMapping(value = "/accounts", method = RequestMethod.POST) 
public String handleRedirect(Model model) { 
    String message = (String) model.asMap().get("message"); 
    return new ModelAndView(); 
} 

因此添加会话属性应该可以用同样的方法。另有参考文献here

编辑 我在浏览Spring文档,他们也提到了这个注释@SessionAttributes。从文档:

类型级别@SessionAttributes注释声明特定处理程序使用的会话属性。这通常会列出应该透明地存储在会话或某些会话存储中的模型属性或模型属性类型的名称,作为后续请求之间的表单支持bean。

这是你需要的吗?

还有a link to documentation on flash attributes

+0

redirectAttributes的主要问题是我需要将所有变量放在单独的属性中,如果它们不是html的形式。 – Raider

2

这是我们拿出,无关与Spring的解决方案:

  1. 在您的应用程序的每个HTML表单,你将不得不包括一个隐藏字段。我们来命名这个字段CSRF_TOKEN。这个字段应该有一个随机生成的值。该值被放置在会话和隐藏字段中。会话属性的名称为SESSION_CSRF_TOKEN

  2. 将表单提交给服务器时,检查会话中的值(SESSION_CSRF_TOKEN)是否等于HTTP请求参数CSRF_TOKEN中发送的值。如果不是,则显示某种错误消息,并停止处理。如果他们是平等的,继续。

如果用户打开新选项卡或复制选项卡,服务器将重新呈现该页面,并且将生成新的CSRF_TOKEN。因此,用户将只能从新打开的选项卡提交表单,而不能从原始表单提交表单。

此解决方案提供额外的奖励:它可以防止CSRF attacks

相关问题