【发布时间】:2012-05-07 09:33:04
【问题描述】:
似乎今天(2012 年 4 月),MyFaces 和 Mojarra 的 JSF 2.1 实现在部分状态保存方面都存在缺陷,应该将 PARTIAL_STATE_SAVING 设置为 false。
这是真的吗?
【问题讨论】:
-
MyFaces 代码没问题。目前(2012-APR)没有与 PSS 相关的未解决问题。一切都按预期工作。
似乎今天(2012 年 4 月),MyFaces 和 Mojarra 的 JSF 2.1 实现在部分状态保存方面都存在缺陷,应该将 PARTIAL_STATE_SAVING 设置为 false。
这是真的吗?
【问题讨论】:
是否应该将 PARTIAL_STATE_SAVING 设置为 false?
仅当您遇到与 web 应用程序中的部分状态保存相关的一般缺陷时,真的无法以其他方式解决/变通。部分状态保存在整体性能和内存使用方面具有主要优势。另见Why JSF saves the state of UI components on server?
我不能 100% 可靠地代表 MyFaces,但在 Mojarra 中,当您绑定标签处理程序的任何属性时,部分状态保存问题的根本原因就会显现出来(标签处理程序可以通过缺少 @ 来识别)标记上的 987654325@ 属性(例如 JSTL 标记)到视图范围 bean,或者当您将 JSF 组件的 id 或 binding 属性绑定到视图范围 bean 时(这些属性即在构建期间解析/恢复视图)。
这个问题是由JSF issue 1492 和JSF spec issue 787 中描述的鸡蛋问题引起的:启用部分状态保存后,视图范围的bean 被存储在部分视图状态中。因此,要提取视图范围的 bean,必须恢复部分视图状态。在恢复(构建)视图期间,将评估所有上述属性中的 EL。但是,由于此时没有可用的视图范围 bean 实例,因此将创建一个全新的实例。但是,这会将其所有属性设置为默认值!在恢复视图并取回原始视图范围的 bean 后,它们将被放回视图范围,覆盖在恢复视图期间创建的(临时)实例。但是这些属性的 EL 表达式已经基于完全不同的实例进行了评估,无法恢复。
自 Mojarra 2.1.18 和 2.2.0 以来,通过在会话中存储视图范围 bean 解决了这个鸡蛋问题。如果由于某种原因无法升级,那么这确实可以通过将javax.faces.PARTIAL_STATE_SAVING 设置为false 来禁用部分状态保存来解决。另一种方法是不将上述属性绑定到视图范围的 bean,而是寻找替代解决方案。
您也可以改为设置javax.faces.FULL_STATE_SAVING_VIEW_IDS。这允许您指定需要关闭部分状态保存的所有视图 ID 的逗号分隔列表:
<context-param>
<param-name>javax.faces.FULL_STATE_SAVING_VIEW_IDS</param-name>
<param-value>/some.xhtml,/other.xhtml</param-value>
</context-param>
这使您可以尽可能地从部分状态保存中受益,并且仅对部分状态保存相关问题实际上无法修复的视图子集关闭它。
【讨论】:
/some.xhtml 和 /other.xhtml。