com.sun.faces.numberOfViewsInSession vs com.sun.faces.numberOfLogicalViews

Mojarra JSF 2的实现具有以下背景参数:

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

他们有什么区别? 这些文档没有提到这些。 我的应用程序对于某些页面的ViewExpiredException有问题,但是当我们将这些设置碰到更高的值时,我们停止了一些问题。

我的应用程序是一个财务,forms沉重,启用Ajax的应用程序(一些屏幕有50多个input,可以通过AJAX添加更多的数据/input的选项)。

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

首先,Mojarra实现无意中交换了这些上下文参数的含义。 所以,如果你有这样的印象,即描述与文本上下文参数名称暗含的意思完全相反,那么的确如此。


com.sun.faces.numberOfLogicalViews

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

要进行实验,将其设置为3,启动一个新的浏览器会话,然后按顺序打开4个不同的浏览器选项卡(不pipeURL是否相同,可能不同),然后返回到第1个选项卡并提交在那里的forms。 你会得到一个ViewExpiredException ,因为这个视图已经从会话中的视图的LRU(最近最less使用)映射中推出。 如果您打开最多3个选项卡,则不会发生这种情况

默认值为15,这是一个罕见的现实世界问题。 如果您的web应用程序确实被devise为以这种方式使用(例如,邀请在多个选项卡(如讨论论坛或问答)中打开的社区/社区站点),则可以考虑使用客户端状态保存,而不是增加默认值。 在客户端状态保存的情况下,您将永远不会面临这个exception。 另一种方法是将OmniFaces <o:enableRestorableView>与请求范围的bean和请求参数结合使用,或者使用视图范围的bean来检查(post)构造是否需要恢复自己的状态。 再一种select是使用<f:view transient="true">来实现无状态 ,这样视图就不会再被保存了,但是不能再使用视图范围的bean了。

MyFaces等价物是org.apache.myfaces.NUMBER_OF_VIEWS_IN_SESSION ,默认为20。


com.sun.faces.numberOfViewsInSession

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

要进行实验,请将其设置为3,用同步表单打开视图,提交4次,然后按浏览器的后退button4次,然后再次提交表单。 您将得到一个ViewExpiredException ,因为这个视图已经从逻辑视图的LRU(最近最less使用)映射中推出。 这不会发生,如果你最多回3次,然后重新提交。

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

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

MyFaces最初并没有这方面的function,并且在会话中也将其视为一个物理视图。 在2.0.6版本中,引入了org.apache.myfaces.NUMBER_OF_SEQUENTIAL_VIEWS_IN_SESSION ,具有类似的用途,但是具有不同的实现,默认情况下禁用。


也可以看看:

  • 为什么JSF在服务器上保存UI组件的状态?
  • PARTIAL_STATE_SAVING应该设置为false吗?
  • javax.faces.application.ViewExpiredException:无法恢复视图
  • JSF中的无状态有什么用处?

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

这可能有帮助:

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