是否在会话范围的 JSF 支持 bean 中观察到 CDI 事件

Posted

技术标签:

【中文标题】是否在会话范围的 JSF 支持 bean 中观察到 CDI 事件【英文标题】:Do CDI Events observed across session scoped JSF backing beans 【发布时间】:2011-05-27 18:50:05 【问题描述】:

我想知道是否可以使用多个 JSF 2.0 会话范围的支持 bean 观察 CDI 事件。我认为我可以通过观察事件将事件/数据推送到多个会话。

我设置了一个小测试,允许用户使用页面上的按钮触发事件(该按钮与会话范围的支持 bean 中实际触发事件的方法相关联)。我认为如果我打开两个不同的浏览器,将创建两个会话,并且该事件将通知每个会话范围的支持 bean。

但是,当运行我的小测试并单击按钮以在其中一个浏览器上触发事件时,我看到该事件仅通知会话范围 bean 之一。它只通知触发事件的 bean(即 - 如果我单击浏览器 1 中的按钮,则会通知支持浏览器 1 中会话的会话范围 bean,如果我单击浏览器 2 中的按钮,则支持会话的 bean浏览器 2 被通知)。

我的印象是事件会通知所有 bean 实例。然而,情况似乎并非如此。我应该能够做到这一点吗?我只是设置有问题吗?

UPDATE 显示我的代码的样子:

jsfpage.xhtml 的 sn-p 触发事件并显示会话范围的数据:

<h:form>
  <h:outputText value="#BackingBean.property" />
  <p:commandButton value="Fire Event" action="#EventFirer.fireEvent" />
</h:form>

接收事件的 Session 范围的 bean:

@Named
@SessionScoped
public class BackingBean implements Serializable 

    private String property;

    public String getProperty() 
        return property
    

    public void listenForChange(@Observes EventObj event) 
        logger.log(Level.INFO, "Event received");
        property = event.toString();
    

一个应用范围的bean来触发事件:

@Named
@ApplicationScoped
public class EventFirer implements Serializable 

    @Inject
    private Event<EventObj> events;

    public String fireEvent() 
        logger.log(Level.INFO, "Event fired");
        events.fire(new EventObj());
        return null;
    

【问题讨论】:

【参考方案1】:

首先,您最好指定事件的类型:

@Inject
private Event<EventObj> events;

除此之外,规范中没有任何指示会限制调用观察者方法的 bean 实例。我会提出一个关于这个的问题(在你正在使用的实现的错误跟踪器中。也许是 Weld?)

【讨论】:

我无法让 javax.enterprise.context.SessionScoped bean 观察由 javax.enterprise.context.ApplicationScoped bean 触发的事件。抛出异常:WELD-001303 No active contexts for scope type javax.enterprise.context.ConversationScoped.【参考方案2】:

我发现所有注册的观察者都被解雇了。

最值得注意的是,如果我有一个 Conversation Scoped bean 上的观察者,并且该 bean 在当前 Conversation 中不活动,那么当触发事件时,会专门创建一个新实例来接收它!

【讨论】:

以上是关于是否在会话范围的 JSF 支持 bean 中观察到 CDI 事件的主要内容,如果未能解决你的问题,请参考以下文章

会话范围和 jsf 重定向

如何在 JSF 中正确使用组件绑定? (会话范围 bean 中的请求范围组件)

Spring 安全性和 JSF:在登录时调用支持 bean 的方法?

在 Web 过滤器中访问会话范围的 JSF 托管 bean

JSF 请求范围的 bean 不断在每个请求上重新创建新的有状态会话 bean?

xml 如果使用JSF作为MVC框架,则使请求和会话范围spring bean可用