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

  1. 在什么时候JSF保存了服务器端UI组件的状态 ,以及从服务器内存中删除了UI组件的状态信息 ? 当应用程序上的login用户浏览页面时,组件的状态会不会在服务器上累积?

  2. 我不明白将UI组件状态保持在服务器上的好处是什么! 是不是直接通过validation/转换的数据到托pipe的豆足够? 我可以或应该尽量避免吗?

  3. 如果有数以千计的并发用户会话,那么在服务器端不会消耗太多的内存? 我有一个应用程序,用户可以发布有关某些主题的博客。 这个博客的规模相当大。 何时会有回传或要求查看博客, 这个大页面数据会被保存为组件状态的一部分吗? 这会吃掉太多的记忆。 这不是一个问题吗?


更新1:

现在,使用JSF时不再需要保存状态。 高性能的无状态JSF实现可供使用。 查看这个博客和这个问题的相关细节和讨论。 此外,JSF规范中还包含一个公开的问题 ,即为JSF提供无状态模式的选项。 (PS如果这是一个有用的function,请考虑投票处理此问题。

更新2(24-02-2013):

一个好消息, 莫哈拉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组件树受dynamic(编程)更改。 JSF只需知道表单显示给最终用户的确切状态,以便在表单被提交回时,可以根据原始JSF组件树提供的信息成功处理整个JSF生命周期服务器。 组件树提供有关请求参数名称,必要的转换器/validation器,绑定的托pipebean属性和操作方法的信息。


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

这两个问题似乎也归结为相同。 无论如何,这是具体实现,也取决于状态是保存在服务器还是客户端。 有点体面的实现会在它过期或队列已满时将其删除。 当状态保存设置为会话时,Mojarra例如具有15个逻辑视图的默认限制。 这可以在web.xml使用以下上下文参数进行configuration:

 <context-param> <param-name>com.sun.faces.numberOfLogicalViews</param-name> <param-value>15</param-value> </context-param> 

另请参阅Mojarra常见问题的其他Mojarra特定的参数和这个相关答案com.sun.faces.numberOfViewsInSession vs com.sun.faces.numberOfLogicalViews


当应用程序上的login用户浏览页面时,组件的状态会不会在服务器上累积?

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

或者,当状态保存设置为客户端时,JSF将不会在会话中存储任何内容。 您可以通过web.xml的以下上下文参数来完成此操作:

 <context-param> <param-name>javax.faces.STATE_SAVING_METHOD</param-name> <param-value>client</param-value> </context-param> 

然后,它将被序列化为隐藏的input字段中的一个encryptionstring,其格式为名称javax.faces.ViewState


我不明白什么保持UI组件的状态在服务器端的好处是。 是不是直接通过validation/转换的数据到托pipe的豆足够? 我能/应该尽量避免吗?

这还不足以确保JSF的完整性和健壮性。 JSF是一个具有单一入口控制点的dynamic框架。 如果没有状态pipe理,就会以某种方式欺骗/破解HTTP请求(例如操纵disabledreadonlyrendered属性),从而让JSF做出不同的和潜在的危险的事情。 它甚至容易遭受CSRF攻击和networking钓鱼。


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

记忆特别便宜。 只要给appserver足够的内存。 或者如果networking带宽比较便宜,只需将状态保存切换到客户端即可。 为了find最佳匹配,只需以最大的并发用户数来压力testing和分析web应用,然后给应用服务器125%〜150%的最大测量内存。

请注意,JSF 2.0在状态pipe理方面已经有了很大的改进。 可以保存部分状态(例如, 只有 <h:form>将被保存,而不是从<html>一直到最后的整个东西)。 莫哈拉例如这样做。 具有10个input字段(每个字段带有标签和消息)和2个button的平均格式不会超过1KB。 在会话中有15个视图,每个会话不应该超过15KB。 约1000个并发用户会话,应该不超过15MB。

您的关注点应该更关注会话或应用程序范围内的真实对象(托pipe的bean和/或甚至DB实体)。 我已经看到了很多代码和项目,这些代码和项目会不必要地将整个数据库表复制到Java内存中,而会话范围bean的味道已经被Java用来代替SQL来过滤/分组/排列logging。 有了〜1000条logging, 每个用户会话很容易超过10MB。