更新会话中保存的对象的正确方法是什么?我是否必须始终对从会话中检索到的已更改状态的对象调用setAttribute()
?我在这里只是指会话属性,已经已创建并存储在会话中 - 而不是新属性。
假设我的会话中存储了Person
个对象,每个请求都会执行:
Person p = (Person) session.getAttribute("person");
然后,'p'引用的对象始终是跨请求返回给您的同一对象。容器(至少Tomcat)不会每次都给你一个新的副本。这里的要点是,如果您随后执行p.setName("Joe the Plumber")
并且未调用setAttribute("person", p)
,则会话中保留的对象仍将更新,您将看到跨请求的更新。
但是,一旦群集和会话复制发挥作用,您通常必须调用setAttribute()
,以便群集代码能够知道何时分发更新的会话对象。我确实意识到一些容器有其他机制来实现这一点,而无需调用setAttribute()
。
这是Servlet规范的灰色区域吗?
答案 0 :(得分:1)
这是Servlet规范的灰色区域吗?
不,不是。当您检索非不可变对象并修改其状态时,更改将反映在可以引用对象的任何位置,在本例中,在会话中保留的内部Map<String, Object>
中。
使用群集时,您需要显式调用HttpSession#setAttribute
以通知服务器您正在更新会话变量,以便在其他群集中更新会话变量。
答案 1 :(得分:1)
是的,这是一个灰色区域。一般而言,J2EE规范不讨论使用群集时的预期行为。
针对Servlet规范打开了一个增强请求: https://java.net/jira/browse/SERVLET_SPEC-1
请随时添加您的观点,了解应该在该问题的规范中添加什么内容。