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

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

  • 我不明白将UI组件保持在服务器上的好处是什么!? 是否不直接将验证/转换的数据传递给托管的bean? 我可以或应该尝试避免它吗?

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


  • 更新1:

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


    更新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组件的状态信息是否从服务器内存中删除?

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

    <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


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

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

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

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

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


    我不明白在服务器端保持UI组件状态的好处是什么。 是否不直接将验证/转换的数据传递给托管的bean? 我能/应该尽量避免吗?

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


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

    记忆特别便宜。 只要给appserver足够的内存。 或者如果您的网络带宽更便宜,只需将状态保存切换到客户端即可。 为了找到最佳匹配,只需对您的Web应用程序进行压力测试并分析预期的最大并发用户数量,然后向应用程序服务器提供最大测量内存的125%〜150%。

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

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

    链接地址: http://www.djcxy.com/p/58675.html

    上一篇: Why JSF saves the state of UI components on server?

    下一篇: How to 'insert if not exists' in php MySQL