Java 对话范围是否是视图范围的适当替代物?
在JSF2.0中,视图范围最明显的用例是具有多个AJAX回发的单个页面。使用CDI而不是JSF托管bean会使我们没有视图范围,因此我们要么实现自己的视图范围,要么使用(可能存在bug的)第三方实现,要么使用对话范围 我的问题是:在典型的AJAX情况下,对话范围是否值得替代视图范围?与视图范围一样,它是否允许每个会话有多个实例?陷阱是什么 我知道其中一个陷阱,即当用户离开页面时,对话范围不会自动删除,而是在超时后删除。但我不确定当用户在对话超时之前导航回该页面时会发生什么 更新Java 对话范围是否是视图范围的适当替代物?,java,jsf-2,cdi,conversation-scope,Java,Jsf 2,Cdi,Conversation Scope,在JSF2.0中,视图范围最明显的用例是具有多个AJAX回发的单个页面。使用CDI而不是JSF托管bean会使我们没有视图范围,因此我们要么实现自己的视图范围,要么使用(可能存在bug的)第三方实现,要么使用对话范围 我的问题是:在典型的AJAX情况下,对话范围是否值得替代视图范围?与视图范围一样,它是否允许每个会话有多个实例?陷阱是什么 我知道其中一个陷阱,即当用户离开页面时,对话范围不会自动删除,而是在超时后删除。但我不确定当用户在对话超时之前导航回该页面时会发生什么 更新 对话范围确实支持
对话范围确实支持每个会话的多个实例。我使用第2章的代码确认了这一点。在任何
@ConversationScoped
cdibeans中,您必须具有以下字段:
@Inject
private Conversation conversation;
无论何时您想要开始对话,您都需要检查bean是否处于transient
状态。否则,将抛出非法状态异常。应该是这样的:
public void beginConversation() {
if (conversation.isTransient()) conversation.begin();
}
通过这样做,您的bean将处于长时间运行状态。因此,如果用户从页面导航到别处,然后再导航回来,您可以随时检查他的对话是否超时,并将他带到他离开的页面
此外,我已经将@ViewScoped
ManagedBean与cdibean一起使用了一段时间。您仍然可以使用@Inject
将CDIBean注入到MangedBean中。不过,我认为你不能反过来做。无论如何,我不知道这是否会导致任何不好的事情发生。然而,到目前为止,我从未遇到过任何问题。如果你真的想使用@ViewScoped
,我想你可以试试:P
更新:
在典型的AJAX情况下,对话范围是否是视图范围的一个有价值的替代品
我认为@ConversationScoped
永远无法完全取代@ViewScoped
与视图范围一样,它是否允许每个会话有多个实例
不,每个会话不能有多个实例。正如我提到的,如果在旧会话仍处于
长时间运行
状态时启动新会话,您将获得非法状态异常
陷阱是什么
与
@RequestScoped
相比,@ViewScoped
的一个主要优点是,用户每次向同一视图提交表单时,不需要重新初始化数据。然而,对于@ConversationScoped
,这一优势被过度利用了。虽然这个问题没有使用@SessionScoped
那么严重,但是只要@ConversationScoped
bean存在,您仍然需要保存启动的数据。会话越长,您可能需要保存的数据就越多。不过,您可以将EJB注入托管bean吗?如果是这样,这难道不意味着实际上没有理由使用CDI来管理JSF作用域吗?这听起来不对……如果您想将EJB注入托管bean,只需使用@EJB
。这对cdibean
和ManagedBean
都有效。此外,使用CDI
的原因不是为了管理JSF作用域。更重要的是,您可以向CDIBeans中注入更多的内容。“此外,使用CDI的原因不是管理JSF作用域。”是的,我明白了。它将以一种与应用服务器的其余部分更加集成的方式管理JSF作用域。我不会接受这个答案,因为我一直在等待一个直接解决这个对话范围用例的答案。但是谢谢你提供的信息+1因为答案至少是有用的。“不,每个会话不能有多个实例。”第54页的答案肯定是错误的。除此之外,它还声明对话与浏览器选项卡/窗口相关联。我可能只是运行一些测试,看看是什么。测试并确认同一会话范围声明的多个实例可以存在于同一会话中。所以在这个阶段,对话范围看起来至少是视图范围的一个可行替代方案。但是仍然存在如何避免在这种情况下使用它的陷阱的问题。我将进一步调查,同时看看其他人对此有何评论。