在我们为解决粘性会话问题所做的许多事情中,其中一项是使会话属性实现可序列化接口。现在有人可以用外行的方式向我解释一下实现这个接口时会发生什么?在实现此接口的类中观察到哪些行为变化?
3 回答
Web 服务器需要跨多个请求保持会话数据。在集群环境中,这些请求可能由共享相同会话数据的不同 Web 服务器提供服务。当会话数据在一个 Web 服务器中更新时,更新后的会话数据需要在其他 Web 服务器之间复制。为此,我们需要将会话数据转换为可以通过网络发送的内容。这种转换称为序列化。反向过程称为反序列化。
当我们将一个类声明为实现 Serializable 时,我们需要保证该类可以安全地进行序列化和反序列化。如果会话数据实现了 Serializable,Web 服务器可以安全地序列化和反序列化会话数据。Web 服务器不会尝试序列化和反序列化未实现 Serializable 的会话数据,因为无法保证该类可以安全地序列化和反序列化。
这里的关键是,如果你的类实现了 Serializable,你需要确保它可以安全地被序列化和反序列化。比如这个类
class MyClass {
private Runtime runtime = Runtime.getRuntime();
}
无法安全地序列化,因为我们无法序列化一个 Web 服务器的“运行时”,并将其发送到其他 Web 服务器。您可以阅读http://docs.oracle.com/javase/6/docs/api/java/io/Serializable.html了解有关 Java 序列化的更多详细信息。
使会话数据可序列化是一种最佳实践。这允许 servlet 容器将会话的内容存储在磁盘上,或者通过网络将会话内容传输到另一台服务器。
在重启的情况下,Web 容器可能会尝试通过尝试序列化存储在会话范围内的所有数据来实现“故障转移”策略,以便在重启完成后恢复数据 - 这只有在此类数据实现时才有效可序列化。
之前的 JSF 帖子还解释了同一个JSF 支持 bean 应该是可序列化的吗?
An instance of a Serializable class can be serialized using Java standard serialization mechanizm, that is written to a stream with java.io.ObjectOutputStream.writeObject
and later read with java.io.ObjectInputStream.readObject