【发布时间】:2019-06-20 09:14:49
【问题描述】:
当尝试存储自定义对象的 List 变量时session.setAttribute 抱怨该变量不可序列化。
【问题讨论】:
标签: java servlets web-applications servlet-3.0
当尝试存储自定义对象的 List 变量时session.setAttribute 抱怨该变量不可序列化。
【问题讨论】:
标签: java servlets web-applications servlet-3.0
您的整个 servlet 会话可以随时序列化到磁盘或其他存储。所以其中的所有对象都必须是可序列化的。
【讨论】:
正如其他答案所解释的,要求会话变量可序列化的目的是允许容器框架使用对象序列化来:
但有趣的是 Servlet 3.0 规范实际上并不要求这样做。相反,它说:
7.7.2 分布式环境
在标记为可分发的应用程序中,所有可分发的请求 会话的一部分必须一次由一个 JVM 处理。容器 必须能够处理放置在
HttpSession类使用setAttribute或putValue方法 适当地。为了满足这些要求,施加了以下限制 条件:
容器必须接受实现
Serializable接口的对象。容器可以选择支持在
HttpSession中存储其他指定对象,例如对 Enterprise 的引用 JavaBeans 组件和事务。会话的迁移将由特定于容器的设施处理。分布式 servlet 容器必须抛出一个
IllegalArgumentException用于容器不能的对象 支持迁移会话存储所需的机制 他们。分布式servlet容器必须支持该机制 迁移实现Serializable的对象所必需的。这些限制意味着开发者可以确保有 除了在 非分布式容器。容器提供者可以确保 可扩展性和服务质量功能,如负载平衡和 通过能够移动会话对象及其 内容,从分布式系统的任何活动节点到 系统的不同节点。
如果我们仔细分析一下,就是说:
分布式容器必须支持对象序列化作为在会话中迁移对象的一种方式。
应用程序不需要标记为可分发。
容器不一定是分布式容器。
容器可能支持迁移对象的其他方式。
那么这是什么意思?好吧,我认为这意味着您的会话对象实现Serializable 的明显要求源于您选择的容器以及您选择实现webapp 的方式。假设您可以更改这些选择。
【讨论】:
servlet 容器(您的应用程序服务器,如 Tomcat)可能希望将会话信息存储到磁盘。这将帮助您在服务器重新启动时保留用户会话,如果它不将每个会话对象都存储在内存中,而只是在需要时查找它,它还可以更有效地管理内存。
所以你的会话对象需要是Serializable。
【讨论】: