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

Mig*_*ing 36 viewstate jsf jsf-2 viewexpiredexception mojarra

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

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

他们之间有什么区别?文档中没有提到这些内容.我的应用程序在ViewExpiredException某些页面遇到问题,但在我们将这些设置提高到(更高)值后,我们就停止了问题.

我的应用程序是一个财务,重量级,支持Ajax的应用程序(有些屏幕有50多个输入,可以选择通过AJAX添加更多数据/输入).

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

Bal*_*usC 66

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


com.sun.faces.numberOfLogicalViews

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

要试验它,将其设置为值3,启动新的浏览器会话并按顺序打开4个不同的浏览器选项卡(无论URL;可能相同,可能不同),然后返回第1个选项卡并提交在那里的形式.您将获得一个ViewExpiredException,因为此视图已从LRU(最近最少使用)地图中推出,用于会话中的视图.如果您打开最多3个选项卡,则不会发生这种情况

默认值为15,这是一个罕见的现实世界问题.如果您的webapp真的被设计为以这种方式使用(例如,邀请在多个选项卡中打开的社交/社区站点,例如讨论论坛或Q&A),那么您可以考虑使用客户端状态保存而不是增加默认值.通过客户端状态保存,您将永远不会遇到此异常.另一种方法是将OmniFaces<o:enableRestorableView>与请求范围的bean和请求参数结合使用,或者使用视图范围bean来检查(post)构造是否需要恢复其自身状态.另一种替代方法是使用无状态<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次然后重新提交,则不会发生这种情况.

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

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

MyFaces原本没有相应的东西,并将其视为会话中的物理视图.在版本2.0.6中,org.apache.myfaces.NUMBER_OF_SEQUENTIAL_VIEWS_IN_SESSION引入了类似的目的,但具有不同的实现,默认情况下禁用.


也可以看看:


tas*_*sel 5

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

这可能会有所帮助:

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