繁体   English   中英

CDI/JSF 如何处理会话超时

[英]CDI/JSF How to handle session timeout

我有一个 Jakarta EE8 ( CDI 2 / Weld / JSF 2.3 / Wildfly ) 应用程序,当用户注销时我需要执行一些清理代码,手动注销很好但是我现在需要在注销时触发一个事件由于会话而自动发生超时,为了处理这个我已经尝试了以下两种方法......

@Named
@SessionScoped
public class HttpSessionObservers implements Serializable {

    /**
     * 
     */
    private static final long serialVersionUID = 1L;
    
    @Inject private Logger log;
    @Inject SecurityContext securityContext;

    @PreDestroy
    public void processSessionScopedDestroying() {
        
        log.debug("Http Session predestroy");   
        Principal principal = securityContext.getCallerPrincipal(); //<----is null
        //...do some cleanup/logging operations on user account
    }

}

上面的@PreDestroy回调在会话超时但登录用户(主体)始终为空时触发,因此他们似乎已经注销,因此我无法获取用户。

@Named
public class HttpSessionObservers implements Serializable {

    /**
     * 
     */
    private static final long serialVersionUID = 1L;
    
    @Inject private Logger log;
    @Inject private Event<UserLogoutEvent> userLogoutEvent;
    
    public void processSessionScopedInit(@Observes @Initialized(SessionScoped.class) HttpSession payload) {
        log.debug("Http Session initialised");
    }

    public void processSessionScopedDestroying(@Observes @BeforeDestroyed(SessionScoped.class) HttpSession payload) {
        //Never fires
        log.debug("Http Session predestroy");   
        Principal principal = securityContext.getCallerPrincipal();
        //...do some cleanup/logging operations on user account
    }

    public void processSessionScopedDestroyed(@Observes @Destroyed(SessionScoped.class) HttpSession payload) {
        log.debug("Http Session destroyed");    
    }
}

在这里,@BeforeDestroyed 事件从未被触发,似乎找不到任何这种工作的例子,它在其他范围内工作正常。

实现您自己的HttpSessionListener并使用@WebListener对其进行注释 容器应该能够识别这一点,并将在您的实现中调用sessionDestroyed()方法。 您的课程符合 CDI 注入的条件,因此在sessionDestroyed()中,您可以触发一个事件并使用 CDI 观察者监听它。

参考: https ://docs.oracle.com/javaee/6/api/javax/servlet/http/HttpSessionListener.html

编辑:

然后试试这个:将您的HttpSessionListener impl 限定为@ApplicationScoped 拥有 sessionId/用户名的同步映射。 sessionCreated()中插入地图,并在sessionDestroyed()中在finally块中删除它。

该容器还将有几个隐式HttpSessionListener ,因此您的容器有可能在会话无效后很长时间被调用。 如果是这种情况,您可以使用另一种技术来首先插入HttpSessionListener impl。 首先尝试上述技术,然后我们可以深入研究。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM