我开发了一个对托管bean有ViewScoped
和SessionScoped
的应用程序。所有需要用户登录的模块,托管bean都在SessionScoped
,非登录页面将在ViewScoped
。目前,问题是当会话超时(默认情况下是30分钟后)时,非登录页面表现得奇怪,其中commandButton没有向服务器发送请求,并且它也发生在具有ajax行为的所有按钮上页。
我还想知道为什么页面的行为与没有会话一样。是因为ViewScoped
只要用户没有导航到其他页面,就会创建一个临时会话来保存页面吗?
我已经尝试了大部分的建议。
答案 0 :(得分:1)
摘自BalusC's Communication in JSF 2.0
•@ ViewScoped:只要您在浏览器窗口/选项卡中与相同的JSF视图进行交互,此范围内的bean就会存在。它是在HTTP请求时创建的,一旦您回发到另一个视图就会被销毁。当您通过GET请求离开/关闭视图时,它不会立即被破坏,但它不再以常规方式访问。 JSF将bean存储在UIViewRoot#getViewMap()中,并将托管bean名称作为键,然后将其存储在会话中。您需要从action(侦听器)方法返回null或void以使bean保持活动状态。将此范围用于使用ajax,数据表和/或若干呈现/禁用属性的更复杂表单,其状态需要在同一浏览器窗口/选项卡(视图)中的后续请求中保留。
•@ SessionScoped:只要HTTP会话存在,此范围内的bean就会存在。它在会话中涉及此bean的第一个HTTP请求时创建,并在HTTP会话失效时(或者从会话映射中手动删除bean时)被销毁。 JSF将bean作为HttpSession的属性存储,并将托管bean名称作为键。它也可以通过ExternalContext#getSessionMap()获得。将此作用域用于纯会话作用域数据,可以在同一会话中的所有浏览器窗口/选项卡(视图)之间安全地共享。例如,登录用户,用户首选项,例如用户特定设置和所选语言/区域设置等。
ViewScoped
bean存储在UIViewRoot中,而UIViewRoot又存储在用户会话中,因此ViewScoped
bean也间接存储在会话中。在会话到期并被销毁之后,ViewScoped
bean也会被销毁,如果您在该LoginBean的代码中引用了预期状态的某些内容,或者您正在使用需要状态的第三方组件(例如.a4j),然后就可以解释这种可疑性。
我建议您为LoginBean切换到RequestScoped
。我从未遇到过需要ViewScoped
支持bean登录应用程序的情况。