无法在HttpSessionListener中注入CDI @SessionScoped(Cannot inject CDI @SessionScoped in HttpSessionListener)

我有一个有状态的会话范围(CDI)EJB,它包含有关用户会话的信息。

@Stateful @SessionScoped public class GestorSesion implements IGestorSesionLocal, Serializable { private final static long serialVersionUID = 1L; private static final Logger log = Logger.getLogger(GestorSesion.class.getName()); @PostConstruct private void init() { log.info("Configurando información de usuario"); log.info("****************************************************************************"); } @Override public void cerrarSesion() { } @Override public ISessionInfo getSesionInfo() { return null; } }

现在,我想从HttpSessionListener调用cerrarSesion() ( closeSession()

public class GestorSesionWeb implements HttpSessionListener { private static final Logger log = Logger.getLogger(GestorSesionWeb.class.getName()); @Inject private Instance<IGestorSesionLocal> gestorSesion; @Override public void sessionCreated(HttpSessionEvent se) { if (log.isLoggable(Level.FINE)) { log.fine("Iniciada sesión web"); } gestorSesion.get().getSesionInfo(); } @Override public void sessionDestroyed(HttpSessionEvent se) { if (log.isLoggable(Level.FINE)) { log.fine("Limpiando sesión al salir"); } try { this.gestorSesion.get().cerrarSesion(); if (log.isLoggable(Level.FINE)) { log.fine("Sesión limpiada sin problemas"); } } catch (Exception e) { log.log(Level.WARNING, "Excepción limpiando sesión", e); } } }

我从webapp直接访问EJB(使用@EJB注入)到我用于JSF的bean(它们也是CDI托管bean)。

我面临的问题是,似乎HttpSessionListener似乎与JSF bean处于不同的“会话范围”。 创建了两个GestorSession实例; 一个从JSF实例化,另一个从HttpSessionListener实例化。

我尝试通过@Inject Instance<IGestorSesionLocal> , @Inject IGestorSesionLocal和BeanManager注入bean,结果相同。

这个错误报告表明它应该正常工作(错误已经解决了我的版本),但我仍然无法解决它。 我环顾四周,但我找到的是与JSF托管bean有关的问答(是的,我可以尝试在JSF托管bean中包装对EJB的引用,但我想首先“正确”尝试它)。

使用WilFly 8.1.0和JDK 7

有任何想法吗?

I have a stateful, session scoped (CDI) EJB that holds the info about the user session.

@Stateful @SessionScoped public class GestorSesion implements IGestorSesionLocal, Serializable { private final static long serialVersionUID = 1L; private static final Logger log = Logger.getLogger(GestorSesion.class.getName()); @PostConstruct private void init() { log.info("Configurando información de usuario"); log.info("****************************************************************************"); } @Override public void cerrarSesion() { } @Override public ISessionInfo getSesionInfo() { return null; } }

Now, I want to call cerrarSesion() (closeSession()) from an HttpSessionListener

public class GestorSesionWeb implements HttpSessionListener { private static final Logger log = Logger.getLogger(GestorSesionWeb.class.getName()); @Inject private Instance<IGestorSesionLocal> gestorSesion; @Override public void sessionCreated(HttpSessionEvent se) { if (log.isLoggable(Level.FINE)) { log.fine("Iniciada sesión web"); } gestorSesion.get().getSesionInfo(); } @Override public void sessionDestroyed(HttpSessionEvent se) { if (log.isLoggable(Level.FINE)) { log.fine("Limpiando sesión al salir"); } try { this.gestorSesion.get().cerrarSesion(); if (log.isLoggable(Level.FINE)) { log.fine("Sesión limpiada sin problemas"); } } catch (Exception e) { log.log(Level.WARNING, "Excepción limpiando sesión", e); } } }

And I access the EJB from the webapp, directly (injecting using @EJB) into the beans that I use for JSF (they are also CDI managed beans).

The issue that I face is that it seems that the HttpSessionListener seems to be in a different "session scope" than the JSF beans. Two instances of GestorSession are created; one instantiated from the JSF and other instantiated from the HttpSessionListener.

I have tried injecting the bean via @Inject Instance<IGestorSesionLocal>, @Inject IGestorSesionLocal and BeanManager, with identical results.

This bug report suggests that it should to work correctly (the bug is solved for my version), but I still cannot get around it. I have looked around, but what I find are Q&A relating to JSF managed beans (yes, I could try to wrap a reference to the EJB in a JSF managed bean, but I would like to try it "correctly" first).

Working with WilFly 8.1.0 and JDK 7

Any ideas?

最满意答案

我想你的pb来自这里:

我从webapp直接访问EJB(使用@EJB注入)到JSF bean中。

当使用带有EJB的CDI时(通过在其上放置一个@Sessionscoped ),你得到了一个也具有EJB性质但不是相反的CDI bean。 换句话说,CDI意识到EJB的本质,但EJB并不了解CDI。

因此,如果要在代码中将EJB作为CDI bean注入,请使用@Inject而不是@EJB 。 从Java EE 6可以@Inject除了EJB远程之外,总是使用@Inject 。

还要确保只使用CDI托管bean而不是CDI和JSF托管bean的混合。

I think your pb comes from here:

And I access the EJB from the webapp, directly (injecting using @EJB) into the JSF beans.

When use CDI with EJB (by putting a @Sessionscoped on it for instance) you got an CDI bean that also has an EJB nature but not the other way around. In other word CDI is aware of the EJB nature but EJB is not aware of CDI.

So if you want to inject an EJB as a CDI bean in your code use @Inject and not @EJB. From Java EE 6 the admitted good practice is to always use @Inject except for EJB remote.

Also be sure to only use CDI managed bean and not a mix of CDI and JSF managed bean.

更多推荐