在任何@ConversationScoped
CDI bean 中,您必须具有以下字段:
@Inject
private Conversation conversation;
每当您想开始对话时,您都需要检查 bean 是否处于transient
状态。否则,IllegalStateException
将被抛出。它会是这样的:
public void beginConversation() {
if (conversation.isTransient()) conversation.begin();
}
通过这样做,您的 bean 将处于该long-running
状态。因此,如果用户离开页面并稍后导航回来,您始终可以检查他的对话是否超时并将他带到他离开的页面。
此外,我已经将@ViewScoped
ManagedBean与CDI bean一起使用了一段时间。您仍然可以使用@Inject
将CDI bean注入MangedBean。我不认为你可以反过来做。无论如何,我不知道这是否会导致以后发生任何不好的事情。但是,到目前为止,我从未遇到任何问题。如果您真的想使用 @ViewScoped
,我认为您可以尝试:P。
更新:
在典型的 AJAX 情况下,对话范围是否值得替代视图范围?
我认为@ConversationScoped
永远无法完全取代@ViewScoped
.
像视图范围一样,它是否允许每个会话有多个实例?
不,每个会话不能有多个实例。正如我所提到的,如果您在旧对话仍处于long-running
状态时开始新对话,您将获得IllegalStateException
.
有哪些陷阱?
@ViewScoped
好吧, over的主要优点之一@RequestScoped
是您不需要每次用户将表单提交到同一个 View 时都重新启动数据。然而,有了@ConversationScoped
,这个优势就被过度使用了。虽然这个问题没有你使用的那么严重,@SessionScoped
但只要@ConversationScoped
bean 存在,你仍然需要保存启动的数据。对话时间越长,您可能需要持有的数据就越多。