Jsf 无法在HttpSessionListener中注入CDI@SessionScoped
我有一个有状态的会话作用域(CDI)EJB,它保存有关用户会话的信息Jsf 无法在HttpSessionListener中注入CDI@SessionScoped,jsf,jakarta-ee,cdi,wildfly-8,Jsf,Jakarta Ee,Cdi,Wildfly 8,我有一个有状态的会话作用域(CDI)EJB,它保存有关用户会话的信息 @Stateful @SessionScoped public class GestorSesion implements IGestorSesionLocal, Serializable { private final static long serialVersionUID = 1L; private static final Logger log = Logger.getLogger(GestorSesion
@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
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);
}
}
}
public类gestorsessionweb实现HttpSessionListener{
私有静态最终记录器log=Logger.getLogger(GestorSesionWeb.class.getName());
@注入
私人案例管理;
@凌驾
已创建公共无效会话(HttpSessionEvent se){
if(日志可隔离(级别精细)){
log.fine(“Iniciada sesión web”);
}
get().GETSESIONFO();
}
@凌驾
public void sessionDestroyed(HttpSessionEvent se){
if(日志可隔离(级别精细)){
log.fine(“Limpiando sesión al-salir”);
}
试一试{
this.gestorSesion.get().cerrarSesion();
if(日志可隔离(级别精细)){
log.fine(“Sesión limpiada罪恶问题”);
}
}捕获(例外e){
log.log(Level.WARNING,“Excepción limpiando sesión”,e);
}
}
}
我从webapp直接访问EJB(使用@EJB
)到我用于JSF的bean中(它们也是CDI管理的bean)
我面临的问题是,HttpSessionListener
似乎与JSF bean处于不同的“会话范围”。创建了两个GestorSession
实例;一个从JSF实例化,另一个从HttpSessionListener实例化
我尝试过通过@injectinstance
、@injectigestorsesionlocal
和BeanManager
注入bean,结果相同
建议它应该能够正常工作(错误在我的版本中已经解决),但我仍然无法摆脱它。我环顾四周,但我发现的是与JSF托管bean相关的Q&A(是的,我可以尝试在JSF托管bean中封装对EJB的引用,但我想先“正确地”尝试一下)
使用WilFly 8.1.0和JDK 7
有什么想法吗?我认为您的pb来自这里: 我从webapp直接访问EJB(使用
@EJB
)导入JSF bean
当将CDI与EJB一起使用时(例如,通过在其上放置一个@Sessionscoped
),您得到了一个CDIBean,它也具有EJB特性,但不是相反。换句话说,CDI知道EJB的本质,但EJB不知道CDI
因此,如果您想将EJB作为CDIBean注入代码中,请使用@inject
而不是@EJB
。从JavaEE6中,公认的良好实践是始终使用@Inject
,EJB远程除外
还要确保只使用CDI托管bean,而不是CDI和JSF托管bean的混合 @BalusC我尝试过,但会话无效不会触发
@PreDestroy
。要么它期望bean超时,要么(正如我在某处读到的,但我有点怀疑)容器正在钝化EJB并丢弃它们,而不调用PreDestroy
EJB。无论哪种方式,@PreDestroy
都不会被调用(至少在短期内),除非我调用@Remove
。对于用户发起的注销,我会这样做,对于超时发起的注销,我会尝试控制它@Stateful
将为您提供一个EJB@SessionScoped
应该为您提供一个CDI管理的bean(我不确定如果没有@命名
,会有什么行为)。如果您严格处理的是@Stateful
,则两个单独的调用不能保证为您提供相同的EJB实例。在同一个类上应用@Stateful
和@SessionScoped
将为您提供一个EJB和一个CDIBean,它们不一定相互了解。充其量,您得到的是一个不一致的bean状态。为什么要将托管bean和EJB组合在一个类定义中?感谢您的帮助!周一我将尝试将@EJB
切换到@Inject
(我今天不在办公室)。对于“CDI vs JSF”这一点,我还不够清楚,JSF bean是CDI管理的bean(但用于显示JSF页面),我将在问题中纠正这一点。