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

Posted

技术标签:

【中文标题】Mojarra 会话中的服务器状态序列化【英文标题】:Server-state serialization in a session in Mojarra 【发布时间】:2016-08-03 03:59:45 【问题描述】:

翻阅一本书的摘要,我发现了这一点:

在服务器端,状态可以存储为浅拷贝或 深拷贝。在浅拷贝中,状态不会在 会议。默认情况下,JSF Mojarra 使用浅拷贝。

我真的无法理解。

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

javax.faces.STATE_SAVING_METHOD 设置为server

还有一个输入隐藏字段javax.faces.ViewState,其值类似于"2870966362946771868:-8449289062699033744"

显然,服务器内部一定已经维护了与上述隐藏字段相对应的状态。

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

此外,我注意到一件事,如果我的托管 bean(ViewScoped) 没有实现标记接口 Serializable 并将 STATE_SAVING_METHOD 设置为 server,那么在 Mojarra 中,NotSerializablEexception 不会不会发生,而在MyFaces 中会发生。

【问题讨论】:

【参考方案1】:

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

它存在对已经在 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 甚至 @987654336 @ 作为非请求范围 bean 的属性。否则会导致Stuck thread at UIComponent.popComponentFromEL、Java Threads at 100% CPU utilization using richfaces UIDataAdaptorBase and its internal HashMap 和java.lang.IllegalStateException at com.sun.faces.context.FacesContextImpl.assertNotReleased 等问题。

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

【讨论】:

以上是关于Mojarra 会话中的服务器状态序列化的主要内容,如果未能解决你的问题,请参考以下文章

序列化 ASPX 页面?

当状态保存方法设置为客户端且用户会话有效时,在集群环境中获取 ViewExpiredException

如何在会话存储在状态服务器(Web Garden)中的多线程中使用会话变量

Servlet之会话(Session)

无法向会话状态服务器发出会话状态请求

无法向会话状态服务器发出会话状态请求