【发布时间】:2015-03-28 21:57:39
【问题描述】:
我有一个有状态的会话范围 (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,结果相同。
This bug report 建议它应该可以正常工作(我的版本已解决该错误),但我仍然无法解决它。我环顾四周,但我发现的是与 JSF 托管 bean 相关的问答(是的,我可以尝试在 JSF 托管 bean 中包装对 EJB 的引用,但我想先“正确”尝试)。
使用 WilFly 8.1.0 和 JDK 7
有什么想法吗?
【问题讨论】:
-
@BalusC 我试过了,但会话失效不会触发
@PreDestroy。要么是它期望 bean 超时,要么(正如我在某处读到的,但我有些怀疑)容器正在钝化 EJB 并在没有调用PreDestroyEJB 的情况下丢弃它们。无论哪种方式,除非我打电话给@Remove,否则不会调用@PreDestroy(至少在短期内)。我为用户启动的注销执行此操作,并且我正在尝试控制超时启动的注销。 -
有些东西在这里看起来不正确。
@Stateful会给你一个 EJB;@SessionScoped应该给你一个 CDI 托管 bean(我不确定如果没有@Named会有什么行为)。如果您严格处理@Stateful,则不能保证两个单独的调用会为您提供相同的EJB 实例。在同一个类上同时应用@Stateful和@SessionScoped将为您提供一个EJB 和一个CDI bean,它们不一定相互了解。充其量,你得到的是一个不一致的 bean 状态。为什么要将托管 bean 和 EJB 组合在一个类定义中?
标签: jsf jakarta-ee cdi wildfly-8