为什么在GET重定向中清除SessionAttributes? [英] Why do SessionAttributes get cleared on GET redirect?
问题描述
为简单起见,这些代码段将被缩短.这样做的目的是获取一个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
.我可以通过将ModelMap
传递给handleUrlParam
方法并手动向Flash属性添加myParam1
来解决此问题,但这似乎违背了我的意图.
为什么在重定向后将SessionAttribute
myParam1
删除?
是否有更好的方法可以从URI中提取参数并将其放在会话中?
更新
所以看来,无论何时使用RedirectAttributes
,都必须确保将要携带的任何SessionAttribute
放入FlashAttributes的重定向中,否则它们将丢失.我想发生这种情况是因为SessionAttribute
从ModelMap
脱离了(使用时被FlashAttributes取代了).这是Spring的错误还是故意的行为?如果是故意的,有人可以解释为什么吗?我认为SessionAttribute
应该一直存在,直到会话会话完成为止.
附录
鉴于提供的已接受答案,我仍然很困惑如何在将URI参数放入用户会话时清除URI参数.我考虑过的一个选择是为我试图存储的半原始对象(java.lang.Integer,java.lang.String)创建一个包装器,因为它们不会被放置在URI字符串上,但这似乎很不明智.我.如果有人能够更好地接受GET参数,将其存储在用户的会话中并从用户的地址栏中清除它们(这将需要重定向),我将很乐意使用它.
因此,我一直在寻找代码和Internet,以查找为什么它不起作用.
Spring有两个完全独立的模型图-一个用于标准视图渲染,另一个用于发布重定向时.可以在基于mavContainer#getModel()
的结果.对于重定向方案,这将返回重定向模型.因此,您在标准Model
/ModelMap
上设置的任何内容都会丢失.
在谈论标准模型属性时,这很有意义.模型主要用于将对象传递给视图.使用重定向时,您要处理的是完全不同的情况.您想通过HTTP重定向传输对象-因此需要单独的 string和基于flash的模型.
但是我的感觉是,当讨论,但是它们都没有解决这个特定问题./p>
是的...这可能是Spring的Jira的主题.并且可能将其归类为错误,因为这会阻止任何人在使用时设置会话模型属性重定向.迫使Spring通过RedirectAttributes#addFlashAttribute
存储您的会话属性是IMO,这是一种黑客行为,本身就是一种 bug .
For simplicity's sake, these code snippets will be shortened. The purpose of this is to take a GET parameter, set it on the session, and redirect back to the GET with the url parameter removed. Basically, URI cleanup. If there's a better/simpler way to do this, I would be glad to hear it.
I have a controller defined as such:
@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!
}
}
Like the code says, somehow myParam1
is being un-set when the redirect happens. I can fix this by passing a ModelMap
to the handleUrlParam
method and manually adding myParam1
to the flash attributes, but that seems to defeat the purpose in my mind.
Why is the SessionAttribute
myParam1
being removed after the redirect?
Is there a better way to pull parameters off the URI and put them on the session?
UPDATE
So it seems that whenever you use RedirectAttributes
at all, you must make sure you put any SessionAttribute
s you want to carry into the redirect on the FlashAttributes or else they will be lost. I imagine this happens because SessionAttribute
s are pulled off the ModelMap
(which is replaced by FlashAttributes when used). Is this a bug in Spring or intentional behavior? If it's intentional, can someone explain why? I thought SessionAttribute
s were meant to stay on until removed by completion of the conversational session.
Similar StackOverflow post here.
Addendum
In light of the accepted answer provided, I am still stumped as to how I can clear the URI parameters while putting them on the user's session. One option I have considered is to create a wrapper for the semi-primitive objects (java.lang.Integer, java.lang.String) I am trying to store because they will not be placed on the URI string, but this seems hacky to me. If anyone has a better way to accept GET parameters, store them on the user's session, and clear those from the user's address bar (which will require a redirect), I will gladly use it.
So I was looking around the code and Internet to find out why it does not work.
Spring has two completely separate model maps - one for standard view rendering and the other one when a redirect is issued. This can be observed in ModelAndViewContainer
.
Now session attribute persistence is done based on the result from mavContainer#getModel()
. For redirect scenarios, this returns the redirect model. Hence whatever you set on the standard Model
/ ModelMap
is lost.
This makes sense when talking about standard model attributes. Model is there mainly to pass objects to views. When using redirects, you are dealing with a completely different situation. You want to transfer objects via HTTP redirect - hence the separated string and flash based model.
However my feeling is that they forgot about session attributes when designing this feature. There are some nice discussion in Spring's Jira, however none of them addresses this specific issue.
So yes... this might be a topic for Spring's Jira. And it might be classified as a bug as this prevents anyone from setting session model attributes when using redirect. Forcing Spring to store your session attribute via RedirectAttributes#addFlashAttribute
is IMO a hack and kind of a bug on its own.
这篇关于为什么在GET重定向中清除SessionAttributes?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!