为什么 JSF 将 UI 组件的状态保存在服务器上? [英] Why JSF saves the state of UI components on server?

查看:20
本文介绍了为什么 JSF 将 UI 组件的状态保存在服务器上?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

  1. JSF在服务器端保存UI组件状态的时间点&UI 组件的状态信息何时从服务器内存中移除?当应用程序上的登录用户浏览页面时,组件的状态会在服务器上不断累积吗?

  1. Until what point in time does JSF save the state of UI components on the server side & when exactly is the UI component's state information removed from the server memory? As a logged-in user on the application navigates though pages, will the state of components keep on accumulating on the server?

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

I don't understand what is the benefit of keeping UI components state on server !? Isn't directly passing the validated/converted data to managed beans enough? Can I or should I try to avoid it?

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

Doesn't that consume too much memory on the server side, if there are thousands of concurrent user sessions? I have an application where users can post blogs on certain topics. This blogs are quite large in size. When there will be post back or request for viewing the blogs, will this big page data be saved as a part of the state of components? This would eat up too much memory. Isn't this a concern ?


更新 1:

现在,不再需要在使用 JSF 时保存状态.可以使用高性能无状态 JSF 实现.请参阅此博客 &这个问题细节&讨论.此外,还有一个开放的 issue 包含在 JSF 规范中,这是一个提供无状态模式的选项对于 JSF.(PS 考虑为问题投票this & this 如果这对您有用.)


Update 1:

Now, it is no longer necessary to save state while using JSF. A high performance Stateless JSF implementation is available for use. See this blog & this question for relevant details & discussion. Also, there is an open issue to include in JSF specs, an option to provide stateless mode for JSF. (P.S. Consider voting for the issues this & this if this is a useful feature for you.)

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 属性和操作方法的信息.

Because HTTP is stateless and JSF is stateful. The JSF component tree is subject to dynamic (programmatic) changes. JSF simply needs to know the exact state as it was when the form had been displayed to the enduser, so that it can successfully process the whole JSF lifecycle based on the information provided by the original JSF component tree when the form has been submitted back to the server. The component tree provides information about the request parameter names, the necessary converters/validators, the bound managed bean properties and action methods.

JSF 将 UI 组件的状态保存在服务器端的时间点是什么时候,UI 组件的状态信息究竟是什么时候从服务器内存中删除的?

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

Those two questions seem to boil down to the same. Anyway, this is implementation specific and also dependent on whether the state is saved on server or client. A bit decent implementation will remove it when it has been expired or when the queue is full. Mojarra for example has a default limit of 15 logical views when state saving is set to session. This is configureable with the following context param in 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

See also Mojarra FAQ for other Mojarra-specific params and this related answer com.sun.faces.numberOfViewsInSession vs com.sun.faces.numberOfLogicalViews

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

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

Technically, that depends on the implementation. If you're talking about page-to-page navigation (just GET requests) then Mojarra won't save anything in session. If they are however POST requests (forms with commandlinks/buttons), then Mojarra will save state of each form in session until the max limit. This enables the enduser to open multiple forms in different browser tabs in the same session.

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

Or, when the state saving is set to client, then JSF won't store anything in session. You can do that by the following context param in web.xml:

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

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

It will then be serialized to an encrypted string in a hidden input field with the name javax.faces.ViewState of the form.

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

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

That's not enough to ensure the integrity and robustness of JSF. JSF is a dynamic framework with a single entry point of control. Without a state management, one would be able spoof/hack HTTP requests in a certain way (e.g. manipulating disabled, readonly and rendered attributes), to let JSF do different -and potentially hazardful- things. It would even be prone to CSRF attacks and phishing.

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

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

Memory is particularly cheap. Just give the appserver enough memory. Or if network bandwidth is cheaper to you, just switch state saving to client side. To find the best match, just stresstest and profile your webapp with expected max amount of concurrent users and then give the appserver 125% ~ 150% of maximum measured memory.

请注意,JSF 2.0 在状态管理方面有了很大改进.可以保存部分状态(例如,将保存 而不是 中的全部内容一直到最后).例如,Mojarra 就是这样做的.具有 10 个输入字段(每个字段带有标签和消息)和 2 个按钮的平均表单不会超过 1KB.会话中有 15 个视图,每个会话不应超过 15KB.有大约 1000 个并发用户会话,这应该不超过 15MB.

Note that JSF 2.0 has improved a lot in state management. It's possible to save partial state (e.g. only the <h:form> will be saved instead of the whole stuff from <html> all the way to the end). Mojarra for example does that. An average form with 10 input fields (each with a label and message) and 2 buttons would take no more than 1KB. With 15 views in session, that should be no more than 15KB per session. With ~1000 concurrent user sessions, that should be no more than 15MB.

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

Your concern should be more focused on the real objects (managed beans and/or even DB entities) in session or application scope. I've seen lot of codes and projects which unnecessarily duplicates the entire database table into Java's memory in flavor of a session scoped bean where Java is been used instead of SQL to filter/group/arrange the records. With ~1000 records, that would easily go over 10MB per user session.

这篇关于为什么 JSF 将 UI 组件的状态保存在服务器上?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆