9

在 JSF 2.0 中,视图范围最明显的用例是具有可能多个 AJAX 回发的单个页面。使用 CDI 而不是 JSF 托管 bean 使我们没有视图范围,因此我们要么实现我们自己的,要么使用(可能充满错误的)第三方实现,要么使用会话范围。

我的问题:在典型的 AJAX 情况下,对话范围是否值得替代视图范围?像视图范围一样,它是否允许每个会话有多个实例?有哪些陷阱?

我知道其中一个陷阱,即当用户离开页面时对话范围不会自动删除,而是在超时后被删除。但我不确定当用户在对话超时之前导航回该页面时会发生什么。

更新

会话范围确实支持每个会话的多个实例。这本书说明了很多,我能够使用来自 ch 的代码来确认这一点。2.

4

1 回答 1

4

在任何@ConversationScopedCDI bean 中,您必须具有以下字段:

@Inject
private Conversation conversation; 

每当您想开始对话时,您都需要检查 bean 是否处于transient状态。否则,IllegalStateException将被抛出。它会是这样的:

public void beginConversation() {
  if (conversation.isTransient()) conversation.begin();
}

通过这样做,您的 bean 将处于该long-running状态。因此,如果用户离开页面并稍后导航回来,您始终可以检查他的对话是否超时并将他带到他离开的页面。

此外,我已经将@ViewScoped ManagedBeanCDI bean一起使用了一段时间。您仍然可以使用@InjectCDI bean注入MangedBean。我不认为你可以反过来做。无论如何,我不知道这是否会导致以后发生任何不好的事情。但是,到目前为止,我从未遇到任何问题。如果您真的想使用 @ViewScoped,我认为您可以尝试:P。

更新:

在典型的 AJAX 情况下,对话范围是否值得替代视图范围?

我认为@ConversationScoped永远无法完全取代@ViewScoped.

像视图范围一样,它是否允许每个会话有多个实例?

不,每个会话不能有多个实例。正如我所提到的,如果您在旧对话仍处于long-running状态时开始新对话,您将获得IllegalStateException.

有哪些陷阱?

@ViewScoped好吧, over的主要优点之一@RequestScoped是您不需要每次用户将表单提交到同一个 View 时都重新启动数据。然而,有了@ConversationScoped,这个优势就被过度使用了。虽然这个问题没有你使用的那么严重,@SessionScoped但只要@ConversationScopedbean 存在,你仍然需要保存启动的数据。对话时间越长,您可能需要持有的数据就越多。

于 2012-01-01T13:16:53.643 回答