为什么会话变量必须可序列化?

时间:2019-01-26 23:43:36

标签: java servlets web-applications servlet-3.0

当尝试存储自定义对象的List变量时
session.setAttribute抱怨该变量不可序列化。

3 个答案:

答案 0 :(得分:2)

您可以随时将整个servlet会话序列化到磁盘或其他存储中。因此,其中的所有对象都必须可序列化。

答案 1 :(得分:1)

正如其他答案所解释的那样,要求会话变量可序列化的目的是允许容器框架将对象序列化用于:

  • 在分布式Web服务实现中迁移服务器实例之间的会话
  • 服务器上的持久会话重新启动或节省内存。

但是有趣的是Servlet 3.0规范实际上并不需要这个。相反,它说:

  

7.7.2分布式环境

     

在标记为可分发的应用程序中,所有请求   会话的一部分必须一次由一个JVM处理。容器   必须能够处理放置在实例中的所有对象   使用HttpSessionsetAttribute方法的putValue类   适当地。为了满足这些要求,施加了以下限制   条件:

     
      
  • 容器必须接受实现Serializable接口的对象。

  •   
  • 容器可以选择支持在HttpSession中存储其他指定的对象,例如对Enterprise的引用   JavaBeans组件和事务。

  •   
  • 会话的迁移将由特定于容器的设施处理。分布式Servlet容器必须抛出一个   IllegalArgumentException适用于容器无法执行的操作   支持迁移会话存储所必需的机制   他们。分布式Servlet容器必须支持该机制   迁移实现Serializable的对象所必需。

  •   
     

这些限制意味着确保开发人员   除了在服务器上遇到的并发问题外,没有其他并发问题   非分布式容器。容器提供商可以确保   可扩展性和服务质量功能,例如负载平衡和   通过具有移动会话对象及其功能的能力进行故障转移   内容,从分布式系统的任何活动节点到   系统的不同节点。

如果我们仔细分析,那就表示:

  • 一个分布式容器必须支持对象序列化,这是在会话中迁移对象的一种方式。

  • 应用程序无需标记为可分发。

  • 容器不必是分布式容器。

  • 容器可能支持其他迁移对象的方式。

那是什么意思?好吧,我认为这意味着您的会话对象实现Serializable的明显要求源于您对容器的选择以及实现Web应用程序的选择方式。假设您可以更改这些选择。

答案 2 :(得分:0)

Servlet容器(您的应用程序服务器,例如Tomcat)可能希望将会话信息存储到磁盘。这将帮助您在重新启动服务器时保留用户会话,并且如果它不将每个会话对象存储在内存中,而是在需要时查找它,则还可以使其更有效地管理内存。

因此,您的会话对象必须为Serializable