更正会话数据的正确语义

时间:2013-10-10 21:35:19

标签: java jsp session servlets

更新会话中保存的对象的正确方法是什么?我是否必须始终对从会话中检索到的已更改状态的对象调用setAttribute()?我在这里只是指会话属性,已经已创建并存储在会话中 - 而不是新属性。

假设我的会话中存储了Person个对象,每个请求都会执行:

Person p = (Person) session.getAttribute("person");

然后,'p'引用的对象始终是跨请求返回给您的同一对象。容器(至少Tomcat)不会每次都给你一个新的副本。这里的要点是,如果您随后执行p.setName("Joe the Plumber")并且未调用setAttribute("person", p),则会话中保留的对象仍将更新,您将看到跨请求的更新。

但是,一旦群集和会话复制发挥作用,您通常必须调用setAttribute(),以便群集代码能够知道何时分发更新的会话对象。我确实意识到一些容器有其他机制来实现这一点,而无需调用setAttribute()

这是Servlet规范的灰色区域吗?

2 个答案:

答案 0 :(得分:1)

  

这是Servlet规范的灰色区域吗?

不,不是。当您检索非不可变对象并修改其状态时,更改将反映在可以引用对象的任何位置,在本例中,在会话中保留的内部Map<String, Object>中。

使用群集时,您需要显式调用HttpSession#setAttribute以通知服务器您正在更新会话变量,以便在其他群集中更新会话变量。

答案 1 :(得分:1)

是的,这是一个灰色区域。一般而言,J2EE规范不讨论使用群集时的预期行为。

针对Servlet规范打开了一个增强请求: https://java.net/jira/browse/SERVLET_SPEC-1

请随时添加您的观点,了解应该在该问题的规范中添加什么内容。