Mojarra 会话中的服务器状态序列化

Server-state serialization in a session in Mojarra

浏览一本书的摘要时,我遇到了这个:

On the server side, the state can be stored as a shallow copy or as a deep copy. In a shallow copy, the state is not serialized in the session. By default, JSF Mojarra uses shallow copy.

我真的无法理解这个。

由于在上述情况下,我们将有-

javax.faces.STATE_SAVING_METHOD 设置为 server,

和一个输入隐藏字段 javax.faces.ViewState,其值有点像这样 "2870966362946771868:-8449289062699033744"

显然,服务器内部肯定维护了一个对应于上述隐藏字段的状态。

但是抽象地说,如果状态没有在会话中序列化,那么它在哪里?

此外,我注意到一件事,如果我的托管 bean(ViewScoped) 没有实现标记接口 SerializableSTATE_SAVING_METHOD 设置为 server,那么在MojarraNotSerializablEexception 不会出现,而在 MyFaces 中会出现。

But going by the abstract, if the state is not serialized in the session, then where it is?

存在对 HTTP 会话中已有实例的引用,而这些实例又不一定被序列化。

这里的关键上下文参数是 javax.faces.SERIALIZE_SERVER_STATE,它在 MyFaces 中默认为 true,在 Mojarra 中默认为 false。当设置为 true 时,您很快就会在错误地不是 Serializable 的工件上看到 NotSerializableException。否则,您将依赖于服务器配置。例如,Tomcat 默认情况下序列化整个 HTTP 会话,包括服务器重启期间的所有属性。某些服务器,尤其是集群中的 运行,甚至可以配置为在运行时序列化整个 HTTP 会话。在这种情况下,您还会在重启或故障转移期间看到 NotSerializableException

Mojarra 计划根据 2.3 将 javax.faces.SERIALIZE_SERVER_STATE 设置默认设置为 true,特别是因为此设置会主动防止不可预见的开发人员错误,例如分配 JSF 工件的不可序列化实例,例如 UIComponent 甚至 FacesContext 作为非请求范围 bean 的属性。否则会导致问题 , and java.lang.IllegalStateException at com.sun.faces.context.FacesContextImpl.assertNotReleased.

另一方面,在旧的 MyFaces 版本中,由于在反序列化过程中使用了错误的类加载器来解析 EJB 代理,此设置破坏了注入到可序列化托管 bean 中的 EJB。根据 MyFaces issue 3581. See also @EJB in @ViewScoped @ManagedBean causes java.io.NotSerializableException,这已在 MyFaces 2.0.15 和 2.1.9 中修复。