我已经阅读了作用域类型(@SessionScoped, @ViewScoped, @ApplicationScope and @RequestScope
)之间的所有差异,但是,我的应用程序仍然存在问题。我有一个带有网格的page-1
,我将所选项目发送到page-2
(page-1
和page-2
都使用相同的backingbean)进行编辑,然后持久化。我的托管bean使用javax.faces.bean.RequestScoped
中的@RequestScoped
,因为我知道这是理想的使用范围,但它不起作用,bean被破坏,数据丢失。
继续讲这个故事,我把注释改为@SessionScoped
,它起作用了,但我想知道这是否是一个好的做法?因为我读到使用@SessionScoped
不是一个好的做法,因为在客户端注销之前,数据将保持活动状态。
最佳实践是选择适当的bean范围(会话范围或另一个)。在您的情况下,要选择的适当范围是@SessionScoped
bean,因为在以下情况下:
-
RequestScoped
:在每个HTTP请求-响应周期之后都会创建一个新的bean,这是您在尝试请求范围时已经遇到的豆子正在被销毁,数据正在丢失
-
ViewScoped
:一旦您导航到另一个页面(在您的案例中为page-2
),就会创建一个新的beanNB:每次使用与
void
或null
不同的返回值与同一页面交互时,还会创建一个新的bean。 -
@ApplicationScoped
:在这个例子中根本没有任何意义(只有当你想在所有用户之间共享数据/状态时才使用它)
我强烈建议您看看这个问答:如何选择正确的bean范围?它提供了关于如何正确选择beans范围的详细解释。
可以考虑其他建议,这取决于您的功能要求和/或应用环境:
-
当您在两个页面中使用同一个bean时,可以考虑使用一个JSF页面并使用
rendered
属性,然后可以将bean注释为@ViewScoped
(在这种情况下,不要忘记在bean的操作方法中返回void
或null
)。你可以在这里找到一些例子:@ViewScoped的优点和缺点或, -
您可以使用新的Flash范围概念,可以在这里找到一个例子:理解JSF2中的Flash范围或,
-
如果您的环境已经支持CDI(或者您可以简单地添加CDI支持),那么使用
@ConversationScoped
将是您的最佳选择,您可以在这里找到一个很好的例子:JSF 2 ConversationScope是如何工作的或, -
根据Kukeltje的评论,您可以使用Apache DeltaSpike提供的
@ViewAccessScoped
或@GroupedConversationScoped
,它们都比std.@ConversationScoped
更灵活。