在 websocket 中注入应用程序范围内的托管 bean

Inject an application scoped managed bean in a websocket

我正在开发实时应用程序。我有 websockets 和应用程序范围的托管 bean。我正在尝试从 websocket 访问应用程序范围内的托管 bean,但我不能。这可能吗?

这是我的 websocket 和托管 bean(应用程序范围):

@ServerEndpoint("/mediador")
@ManagedBean(eager = true)
@ApplicationScoped
public class Mediador implements Serializable {

@ManagedProperty(value = "#{aplicacion}")
    private Aplicacion aplicacion;
...

还有我的 "Aplicacion" 托管 bean:

@ManagedBean(eager = true)
@ApplicationScoped
public class Aplicacion implements Serializable {
...

如果我尝试在 Mediador class 中访问去托管 属性 "aplicacion" 它是空的,所以我得到一个 NullPointerException。

谢谢

这确实不对

@ServerEndpoint("/mediador")
@ManagedBean(eager = true)
@ApplicationScoped
public class Mediador implements Serializable {

WS (JSR-356 WebSocket) API 和 JSF API 是完全独立的。他们彼此一无所知,不会考虑彼此的混合注释。

实际上,您最终得到了 class 的 两个 个实例。一个作为 ws://.../mediador 可用的 WS 托管服务器端点,一个作为 #{mediador} 可用的 JSF 托管 bean。 @ManagedProperty 只能被 JSF 托管 bean 工具识别,它只能在 JSF 托管 bean 实例中工作。

改为使用 CDI。它适用于整个 Java EE Web 应用程序。不仅在 WebSocket 端点中,而且在 JSF 托管 bean、WebServlets、WebFilters、WebListeners、JAX-RS 资源、JAX-WS 资源等中。最终,JSF managed bean facility 将被弃用,取而代之的是 CDI。这将发生在 Java EE 9 或可能已经是 8.

@ServerEndpoint("/mediador")
public class Mediador { // Shouldn't be serializable!

    @Inject
    private Aplicacion aplicacion;

    // ... (no getter+setter needed!)
}
@Named
@ApplicationScoped // javax.enterprise.context 
public class Aplicacion { // Shouldn't be serializable!

    // ...

}

与具体问题无关:正确地在 JSF 中实现 websockets 并不是微不足道的,如果你想考虑 JSF 会话和视图范围,当然不是喜欢能够在推送期间针对特定用户。你最好看看现有的推送组件。另见 How can server push asynchronous changes to a HTML page created by JSF?