为什么在GET重定向中清除SessionAttributes? [英] Why do SessionAttributes get cleared on GET redirect?

查看:221
本文介绍了为什么在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.我可以通过将ModelMap传递给handleUrlParam方法并手动向Flash属性添加myParam1来解决此问题,但这似乎违背了我的意图.

为什么在重定向后将SessionAttribute myParam1删除?

是否有更好的方法可以从URI中提取参数并将其放在会话中?

更新

所以看来,无论何时使用RedirectAttributes,都必须确保将要携带的任何SessionAttribute放入FlashAttributes的重定向中,否则它们将丢失.我想发生这种情况是因为SessionAttributeModelMap脱离了(使用时被FlashAttributes取代了).这是Spring的错误还是故意的行为?如果是故意的,有人可以解释为什么吗?我认为SessionAttribute应该一直存在,直到会话会话完成为止.

类似的StackOverflow此处.

附录

鉴于提供的已接受答案,我仍然很困惑如何在将URI参数放入用户会话时清除URI参数.我考虑过的一个选择是为我试图存储的半原始对象(java.lang.Integer,java.lang.String)创建一个包装器,因为它们不会被放置在URI字符串上,但这似乎很不明智.我.如果有人能够更好地接受GET参数,将其存储在用户的会话中并从用户的地址栏中清除它们(这将需要重定向),我将很乐意使用它.

解决方案

因此,我一直在寻找代码和Internet,以查找为什么它不起作用.

Spring有两个完全独立的模型图-一个用于标准视图渲染,另一个用于发布重定向时.可以在讨论,但是它们都没有解决这个特定问题./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 SessionAttributes you want to carry into the redirect on the FlashAttributes or else they will be lost. I imagine this happens because SessionAttributes 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 SessionAttributes 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屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆