1

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

假设Person我的会话中存储了一个对象,并且每个请求都执行以下操作:

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

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

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

这是 Servlet 规范的灰色地带吗?

4

2 回答 2

1

这是 Servlet 规范的灰色地带吗?

不它不是。当您检索非不可变对象并修改其状态时,更改将反映在可以引用该对象的任何地方,在这种情况下,Map<String, Object>在会话中保存的内部。

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

于 2013-10-10T21:46:15.280 回答
1

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

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

请随时就该问题的规范中添加的内容(如果有的话)添加您的看法。

于 2013-10-10T22:05:27.347 回答