为什么JSF在服务器上保存UI组件的状态?

  1. 直到什么时候JSF才在服务器端保存UI组件的状态&UI组件的状态信息何时从服务器内存中删除?当应用程序上的登录用户浏览页面时,组件的状态是否会在服务器上不断累积

  2. 在服务器上保留组件的好处是什么直接将验证/转换后的数据传递给托管bean还不够吗?我可以或者应该尽量避免吗

  3. 如果有数千个并发用户会话,那么这不会消耗服务器端太多的内存吗?我有一个应用程序,用户可以在其中发布关于特定主题的博客。这个博客的规模相当大。当有回帖或查看博客的请求时,这个大页面数据是否会作为组件状态的一部分保存?这会占用太多内存。这不是个问题吗


更新1:

现在,在使用JSF时不再需要保存状态。可以使用高性能无状态JSF实现。请参阅此博客&有关详情及;讨论另外,JSF规范中还存在一个开放的问题,即为JSF提供无状态模式的选项。
(P.S.考虑对这些问题进行投票,如果这对你来说是一个有用的特征。)

更新2(24-02-2013):

一个好消息是,Mojarra 2.1.19使用了无状态模式

请看这里:

http://weblogs.java.net/blog/mriem/archive/2013/02/08/jsf-going-stateless?force=255

http://java.net/jira/browse/JAVASERVERFACES-2731

http://balusc.blogspot.de/2013/02/stateless-jsf.html

为什么JSF需要在服务器端保存UI组件的状态?

因为HTTP是无状态的,JSF是有状态的。JSF组件树受到动态(编程)更改的影响。JSF只需要知道表单显示给最终用户时的确切状态,这样当表单提交回服务器时,它就可以基于原始JSF组件树提供的信息成功地处理整个JSF生命周期。组件树提供有关请求参数名称、必要的转换器/验证器、绑定的托管bean属性和操作方法的信息


直到什么时候JSF才在服务器端保存UI组件的状态,以及UI组件的状态信息何时从服务器内存中删除?

这两个问题似乎归结为同一个问题。无论如何,这是特定于实现的,还取决于状态是保存在服务器上还是保存在客户机上。当它已过期或队列已满时,稍微适当的实现将删除它。例如,当statesaving设置为session时,Mojarra的默认限制是15个逻辑视图。这可以在web.xml中使用以下上下文参数进行配置:

<上下文参数>
<参数名称>com.sun.faces.numberofLogicalView&lt/参数名称>
<参数值>15&lt/参数值>
&lt/上下文参数>

另请参阅Mojarra常见问题解答,以了解其他Mojarra特定参数和相关答案com.sun.faces.numberofviewsin会话vs com.sun.faces.numberOfLogicalViews


当应用程序上的登录用户浏览页面时,服务器上的组件状态是否会继续累积?

从技术上讲,这取决于实施情况。如果您谈论的是页面到页面的导航(只获取请求),那么Mojarra不会在会话中保存任何内容。但是,如果它们是POST请求(带有命令链接/按钮的表单),Mojarra将在会话中保存每个表单的状态,直到达到最大限制。这使最终用户能够在同一会话中在不同的浏览器选项卡中打开多个表单

或者,当statesaving设置为client时,JSF将不会在会话中存储任何内容。您可以通过web.xml中的以下上下文参数来执行此操作:

<上下文参数>
<参数名称>javax.faces.STATE\u保存方法&lt/参数名称>
<参数值>客户&lt/参数值>
&lt/上下文参数>

然后,它将被序列化为隐藏输入字段中的加密字符串,该字段的名称为javax.faces.ViewState


我不明白将UI组件的状态保留在服务器端有什么好处。直接将经过验证/转换的数据传递给托管bean还不够吗?我可以/应该避免吗?

这还不足以确保JSF的完整性和健壮性。JSF是一个具有单个入口控制点的动态框架。如果没有状态管理,人们将能够以某种方式欺骗/攻击HTTP请求(例如,操纵禁用的只读的呈现的属性),让JSF做不同的事情,并且可能是危险的。它甚至容易受到CSRF攻击和网络钓鱼


如果有数千个并发用户会话,这不会在服务器端消耗太多内存吗?我有一个应用程序,用户可以在其中发布关于特定主题的博客。这个博客的规模相当大。当有回帖或查看博客的请求时,大型博客将作为组件状态的一部分保存。这将消耗太多内存。这不是个问题吗?

内存特别便宜。只需给appserver足够的内存。或者,如果网络带宽对您来说比较便宜,只需将状态保存切换到客户端即可。要找到最佳匹配,只需使用预期的最大并发用户量对您的webapp进行压力测试和评测,然后为appserver提供125%~150%的最大测量内存

注意,JSF2.0在状态管理方面改进了很多。可以保存部分状态(例如,只保存<h:form>而不是从<html>一直保存到最后的全部内容)。例如,莫哈拉就是这样做的。一个包含10个输入字段(每个字段都有一个标签和消息)和2个按钮的平均表单不超过1KB。会话中有15个视图,每个会话不应超过15KB。对于约1000个并发用户会话,这应该不超过15MB

您应该更关注会话或应用程序范围中的真实对象(托管bean和/或甚至DB实体)。我见过很多代码和项目,它们不必要地将整个数据库表复制到Java内存中,就像会话作用域bean一样,在会话作用域bean中使用Java而不是SQL来过滤/分组/排列记录。对于约1000条记录,每个用户会话的容量很容易超过10MB

发表评论