37

JSF 2 的 Mojarra 实现具有以下上下文参数:

  • com.sun.faces.numberOfViewsInSession(默认为 15)
  • com.sun.faces.numberOfLogicalViews(默认为 15)

它们之间有什么区别?文档并没有过多地谈论这些。我的应用程序在某些页面上遇到了问题ViewExpiredException,但是在我们将这些设置提高到(更高)值之后,我们就不再遇到问题了。

我的应用程序是一个财务、表单繁重、启用 ajax 的应用程序(某些屏幕有 50 多个输入,可以选择通过 AJAX 添加更多数据/输入)。

这种行为的原因是什么?我知道第一个参数定义了会话中保留的“页面”数量,这可能对后退按钮很有用,但我触发的用例ViewExpiredException不使用后退按钮。第二个参数指的是什么?如果我留在同一个屏幕上,但通过 AJAX 继续添加大量数据,这是否会导致页面需要大量逻辑视图?

4

2 回答 2

68

首先,Mojarra 实现无意中交换了这些上下文参数的含义。因此,如果您的印象是描述与字面上下文参数名称所暗示的完全相反,那么这确实是正确的。


com.sun.faces.numberOfLogicalViews

这基本上是基于 GET 请求的。每个 GET 请求都会在会话中创建一个新视图。

为了试验它,将其设置为 3,启动一个新的浏览器会话并依次打开 4 个不同的浏览器选项卡(不管 URL;可能相同,可能不同),然后返回第一个选项卡并提交里面的表格。您将得到一个ViewExpiredException,因为该视图已从 LRU(最近最少使用)映射中推出,用于会话中的视图。如果您打开最多 3 个选项卡,则不会发生这种情况。

默认值为 15,这是一个罕见的现实世界问题。如果您的 web 应用程序确实设计为以这种方式使用(例如,邀请在多个选项卡中打开的社交/社区站点,例如讨论论坛或问答),那么您可能会考虑使用客户端状态保存而不是增加默认值. 使用客户端状态保存,您将永远不会遇到此异常。另一种方法是结合使用OmniFaces<o:enableRestorableView>请求范围的 bean 和请求参数,或视图范围的 bean,如果它自己的状态需要恢复,则检查(后)构造。另一种选择是使用无状态<f:view transient="true">,这样视图不再保存,但您不能再使用视图范围的 bean。

MyFaces 等效org.apache.myfaces.NUMBER_OF_VIEWS_IN_SESSION项默认为 20。


com.sun.faces.numberOfViewsInSession

这基本上是基于同步(非 ajax!)POST 请求的。每个同步 POST 请求都会创建一个新的逻辑视图。它们都存储在这样的物理视图的基础上Map<PhysicalView, Map<LogicalView, ViewState>>。因此,最多 15 个物理视图和最多 15 个逻辑视图,理论上您可以在会话中拥有 15*15 = 225 个视图。

为了试验它,将其设置为 3,打开一个同步表单的视图,提交 4 次,然后按浏览器的后退按钮 4 次,然后再次提交表单。你会得到一个ViewExpiredException, 因为这个视图已经从逻辑视图的 LRU(最近最少使用)映射中推出。如果您最多返回 3 次然后重新提交,则不会发生这种情况。

javax.faces.ViewState请注意,ajax 提交重用相同的逻辑视图(您可以通过查看在 ajax 回发上返回的完全相同的值来确认它)。无论如何,没有浏览器的后退按钮支持。浏览器的后退按钮只会让您回到之前的同步请求,因此将所有这些 ajax 回发存储为会话中的逻辑视图是没有任何意义的。

使用默认值 15 以及当前仅 ajax 表单和禁用动态页面上的缓存的趋势,这是一个非常罕见的现实世界问题。正确设计的表单不应邀请按下浏览器的后退按钮。相反,他们应该成功提交重定向到目标视图,失败时只需重新显示带有验证错误的相同表单。另请参阅如何在 JSF 中导航?如何使 URL 反映当前页面(而不是上一个页面)。此外,缓存在动态页面上经常被禁用,所以返回按钮基本上会给你一个全新的视图。另请参阅避免 JSF Web 应用程序上的后退按钮。如果这也是您的应用程序的情况,那么您可以安全地将值设置为 1。

MyFaces 最初对此没有等效项,并且也将其视为会话中的物理视图。在 2.0.6 版中,org.apache.myfaces.NUMBER_OF_SEQUENTIAL_VIEWS_IN_SESSION引入了类似的目的,但实现方式不同并且默认禁用。


也可以看看:

于 2013-04-17T02:30:12.357 回答
5

刚在网上找到这个:http: //oss.org.cn/ossdocs/java/ee/javaeetutorial5/doc/JSFConfigure11.html

这可能会有所帮助:

逻辑视图是顶级视图的子视图。例如,如果您的页面包含多个框架,那么每个框架都是一个逻辑视图。如果您有一个简单的应用程序,那么默认的 15 个视图或 15 个逻辑视图可能会太大。在这种情况下,您应该考虑减少允许的视图和逻辑视图数量以节省内存。相反,更复杂的应用程序可能需要在一个会话中保存超过 15 个视图或逻辑视图。

于 2010-11-11T12:10:44.140 回答