@SessionScoped 是一个好习惯吗?

Is @SessionScoped a good practice?

我已经了解了范围类型之间的所有差异 (@SessionScoped, @ViewScoped, @ApplicationScope and @RequestScope),但是,我的应用程序仍然面临某种问题。我有一个带有网格的 page-1,我将所选项目发送到 page-2page-1page-2 都使用相同的支持 bean)进行编辑,然后保存.我的托管 bean 使用的是 javax.faces.bean.RequestScoped 中的 @RequestScoped,据我所知,这是理想的使用范围,但它不起作用,bean 被破坏,数据丢失。

继续讲故事,我已将注释更改为 @SessionScoped 并且它起作用了,但我想知道这是否是一种好的做法?因为我读过使用 @SessionScoped 不是一个好习惯,因为数据将一直保持到客户端注销为止。

最佳做法是选择合适的 bean 范围(会话范围或其他范围)。 适当的范围选择在你的情况下是@SessionScoped bean,因为在以下情况下:

  • RequestScoped:在每个 HTTP 请求-响应周期后都会创建一个新 bean,您在尝试请求范围时已经遇到过:

    the bean was being destroyed and the data was getting lost

  • ViewScoped:导航到另一个页面后将创建一个新 bean(在您的情况下为 page-2

    注意: 每次使用 return 值 不同[=68= 与同一页面交互时,也会创建一个新 bean ] 比 voidnull.

  • @ApplicationScoped:在那个例子中根本没有任何意义(只有当你想在所有用户之间共享 data/state 时才使用它)

我强烈建议您看一下这个 Q/A:How to choose the right bean scope? 它提供了有关如何正确选择 beans 范围的详细说明。

可以考虑其他建议,这取决于您的功能要求和/或应用环境:

  1. 由于您在两个页面中使用相同的 bean,您可以考虑使用一个单独的 JSF 页面并使用 rendered 属性,然后您可以将 bean 注释为 @ViewScoped(在这种情况下,不要忘记在 bean 的操作方法中使用 return voidnull)。您可以在此处找到一些示例:The benefits and pitfalls of @ViewScoped,

  2. 您可以使用新的 Flash scope concept, an example could be found here: Understand Flash Scope in JSF2,

  3. 如果您的环境已经支持 CDI(或者您可以简单地添加 CDI 支持),那么使用 @ConversationScoped would be the best choice regarding your case, you may find a good example here: How does JSF 2 ConversationScope work?,

  4. 根据 Kukeltje 的评论,您可以使用 @ViewAccessScoped or @GroupedConversationScoped provided by Apache DeltaSpike,它们都比 std 更灵活。 @ConversationScoped.