我已经阅读了范围类型(@SessionScoped, @ViewScoped, @ApplicationScope and @RequestScope
)之间的所有差异,但是,我仍然面临着应用程序的问题。我有一个带有网格的page-1
,我将所选项目发送到page-2
(page-1
和page-2
都使用相同的支持bean)进行编辑然后保留。我的托管bean正在使用来自@RequestScoped
的{{1}},因为我知道它是理想的使用范围,但它不起作用,bean被破坏而数据丢失了。
恢复故事,我已将注释更改为javax.faces.bean.RequestScoped
并且它有效但我想知道它是否是一个好的做法?因为我已经读过使用@SessionScoped
不是一个好习惯,因为在客户端注销之前数据将保持活动状态。
答案 0 :(得分:4)
最佳做法是选择适当的bean范围(会话范围或另一个范围)。在您的情况下,适当的范围是@SessionScoped
bean,因为在以下情况下:
RequestScoped
:在每次HTTP请求 - 响应周期后都会创建一个新bean,这是您在尝试请求范围时遇到的:
豆被破坏,数据丢失
ViewScoped
:导航到另一个页面后会创建一个新bean(在您的情况下为page-2
)
NB:每次使用返回值不同而不是void
或{{1}与同一页面进行互动时,也会创建新的bean }。
null
:在该示例中没有任何意义(仅在您希望在所有用户之间共享数据/状态时使用它)
我强烈建议您查看此问答:How to choose the right bean scope?,其中提供了有关如何正确选择Bean范围的详细说明。
可以考虑其他建议,这取决于您的功能要求和/或应用程序环境:
当您在两个页面中使用相同的bean时,您可以考虑使用单个JSF页面并使用@ApplicationScoped
属性,然后您可以将您的bean注释为rendered
(在这种情况下,不要忘记在bean的动作方法中返回@ViewScoped
或void
。您可以在此处找到一些示例:The benefits and pitfalls of @ViewScoped。 或强>,
您可以使用新的Flash scope概念,可以在此处找到一个示例:Understand Flash Scope in JSF2。 或强>,
如果你的环境已经支持CDI(或者你可以简单地添加CDI支持),那么使用@ConversationScoped
将是关于你的案例的最佳选择,你可以在这里找到一个很好的例子:{{3 }}。 或强>,
根据Kukeltje的评论,您可以使用How does JSF 2 ConversationScope work?提供的@ViewAccessScoped
或@GroupedConversationScoped
,它们比标准版更灵活。 null
。