为什么在GET重定向中清除SessionAttributes?
问题内容:
为简单起见,这些代码段将被缩短。这样做的目的是获取一个GET参数,在会话上进行设置,然后重定向回去掉url参数的GET。基本上,URI清理。如果有更好/更简单的方法可以做到这一点,我将很高兴听到它。
我有一个这样定义的控制器:
@Controller
@RequestMapping("/path/page.xhtml")
@Scope(BeanDefinition.SCOPE_PROTOTYPE)
@SessionAttributes({ "myParam1", "myParam2" })
public class MyController {
@RequestMapping(method = RequestMethod.GET, params = { "urlParam2" })
public String handleUriParam(@RequestParam(value = "urlParam2", required = false)
final Long urlParam2,
final RedirectAttributes redirs) {
// at this point, myParam1 is set on the session.
// now set the param as a flash attrib with the name of the session variable
redirs.addFlashAttribute("myParam2", urlParam2);
return "redirect:/path/page.xhtml";
}
@RequestMapping(method = RequestMethod.GET, params = {})
public String doGetStuff(ModelMap model) {
// do stuff using myParam1 and myParam2.
// problem is, myParam2 is on the session, but myParam1 is not!
}
}
就像代码中所说的那样,myParam1
重定向发生时会以某种方式取消设置。我可以通过将a传递ModelMap
给handleUrlParam
方法并手动添加myParam1
到flash属性来解决此问题,但这似乎违背了我的意图。
为什么SessionAttribute
myParam1
在重定向后被删除?
有没有更好的方法可以从URI中提取参数并将其放在会话中?
更新
因此,似乎无论何时使用RedirectAttributes
,都必须确保将SessionAttribute
要携带的任何内容放入FlashAttributes的重定向中,否则它们将丢失。我想发生这种情况是因为SessionAttribute
s脱离了ModelMap
(使用时被FlashAttributes取代了)。这是Spring的错误还是故意的行为?如果是故意的,有人可以解释原因吗?我认为SessionAttribute
s应当一直保留,直到会话会话完成为止。
附录
鉴于提供的接受的答案,我仍然很困惑如何在将其放入用户会话时清除URI参数。我考虑过的一个选择是为我试图存储的半原始对象(java.lang.Integer,java.lang.String)创建一个包装器,因为它们不会被放置在URI字符串上,但是这样做似乎很麻烦我。如果有人能够更好地接受GET参数,将其存储在用户的会话中,然后从用户的地址栏中清除它们(这将需要重定向),我将很乐意使用它。
问题答案:
因此,我在浏览代码和Internet,以查明为什么它不起作用。
Spring有两个完全独立的模型图-
一个用于标准视图渲染,另一个用于发布重定向时。可以在中观察到ModelAndViewContainer
。
现在,会话属性的持久性基于的结果mavContainer#getModel()
完成。对于重定向方案,这将返回重定向模型。因此,您在标准Model
/
上设置的任何内容ModelMap
都会丢失。
在谈论标准模型属性时,这很有意义。模型主要用于将对象传递给视图。使用重定向时,您要处理的是完全不同的情况。您想通过HTTP重定向传输对象-因此需要
基于字符串和Flash 的分离模型。
但是我的感觉是,在设计此功能时,他们忘记了会话属性。Spring的Jira中有一些不错的讨论,但是没有一个解决这个特定的问题。
所以是的…这可能是Spring的Jira的主题。 而且它 可能被归类为错误,
因为这会阻止任何人在使用重定向时设置会话模型属性。强迫Spring通过RedirectAttributes#addFlashAttribute
IMO
来存储您的会话属性是IMO 本身 的一种 缺陷 。