这是可以重现此问题的代码:
@Controller
public class FirstController {
@RequestMapping(value = "firstpage", method = GET)
public String myHander(HttpSession httpSession) {
if (httpSession.getAttribute("someClass") == null) {
httpSession.setAttribute("someClass", new SomeClass());
}
return "firstpage";
}
}
第一个控制器会在会话中放入一些内容(如果它尚未存在)。
@Controller
@SessionAttributes(types = SomeClass.class)
public class SecondController {
@RequestMapping(value = "secondpage", method = GET)
public String myHandler(SomeClass someClass, HttpSession httpSession) {
//asking spring for the SomeClass parameter, that's why we put it in the annotation.
System.out.print(someClass.hashCode());
httpSession.invalidate();
return "secondpage";
}
}
第二个控制器终止会话。
在两个jsp文件中,我有以下代码打印会话对象的哈希码和会话属性的哈希码:
session hash:
<%= session.hashCode() %>
<br/>
someclass hash:
<%= session.getAttribute("someClass").hashCode() %>
现在如果我运行应用程序并访问“firstpage”,我会得到这个:
会话哈希:1838367636
someclass hash:1075505853
然后我访问“secondpage”,并得到这个:
会话哈希:842656294
someclass hash:1075505853
我们可以看到会话本身已更改,因为第二个控制器会终止会话。但是session属性(SomeClass类型)保持不变。
然后,如果我尝试重新访问“secondpage”,会话对象每次都会更改,但会话属性保持不变。
为什么会话属性(应该附加到会话)的生命周期比会话本身更长?
你可以使用mvn jetty运行它:运行以重现问题。
答案 0 :(得分:1)
此注释的documentation不是特别清楚,但我的理解是它用于在同一控制器中的方法之间共享值。当我读到以下内容时:
这通常会列出模型属性的名称或模型属性的类型,这些属性应该透明地存储在会话或某些会话存储中,作为后续请求之间的表单支持bean
我将其解释为每个控制器方法调用都将通过调用包装(1)在进入之前加载会话属性,以及(2)将它们存储在出口处。哪个会有你所看到的行为。
注释的javadoc中的以下内容加强了(imo):
对于永久会话属性,例如用户身份验证对象,请使用传统的session.setAttribute方法
如果他们告诉您使用标准功能修改会话,则表明注释不仅仅是访问会话中项目的方式。
对于最终数据点:如果此注释 是管理会话数据的方式,那么为什么要使用会话范围的bean?