在JSF 2.0中,视图范围最明显的用例是可能有多个AJAX回发的单个页面。使用CDI而不是JSF托管bean使我们没有视图范围,所以我们要么继续实现我们自己的,使用(可能是错误的)第三方实现或使用会话范围。
我的问题:在典型的AJAX情况下,会话范围是否值得替代视图范围?与视图范围一样,它是否允许每个会话有多个实例?有什么陷阱?
我知道其中一个陷阱,即当用户离开页面时会自动删除会话范围,而是在超时后删除。但是我不确定当用户在对话超时之前将返回导航到该页面时会发生什么。
更新
会话范围确实支持每个会话多个实例。 This book说明了这一点,我能够使用ch中的代码来确认这一点。 2。
答案 0 :(得分:4)
在任何@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
优于@RequestScoped
的一个主要优点是,每次用户将表单提交到同一个View时,您都不需要重新启动数据。但是,对于@ConversationScoped
,此优势被过度使用。虽然这个问题并不像使用@SessionScoped
那么严重,但只要@ConversationScoped
bean存在,您仍需要保留启动的数据。会话越长,您可能需要保留的数据就越多。