JSF会话过期阶段侦听器如果浏览器关闭



在用户关闭浏览器并离开的情况下,我希望在会话超时时登录。例如,作为系统引发的注销,而不是用户请求(我已经有了工作和测试的代码来记录用户请求的注销)。

由于用户没有主动提交请求(尤其是如果这只是服务器上现在未使用的会话超时的问题),我认为过滤器是不可能的。这可以用相位监听器完成吗?如果是的话,你能提供一些见解或骨架吗,或者至少为我指明如何做到这一点的正确方向。

我的理解是,服务器上的会话仍然处于活动状态,直到超时或其他机制使其无效。因此,我假设阶段侦听器也能够判断,作为登录方法的一部分,您是否在用户使用新视图、其他机器等再次登录之前终止了任何现有会话。

我对研究还可以,但至少要从正确的方向开始。:)

关于第二个问题:是否可以区分会话超时和视图过期


我想我会发布基于建议的解决方案:

public class ElsSoulardSessionListener implements HttpSessionListener {
    @EJB
    private SessionLogger sessionLogger = new SessionLogger();
    private SessionLogDTO sessionData = new SessionLogDTO();
    private ElsDateTimeFunctions ts = new ElsDateTimeFunctions();
    private static final Logger logger = Logger.getLogger(ElsSoulardSessionListener.class.getSimpleName());
    @Override
    public void sessionCreated(HttpSessionEvent se) {
        // Nothing to do yet
    }
    @Override
    public void sessionDestroyed(HttpSessionEvent se) {
        logger.log(Level.FINE, "SESSION DESTROYED LISTENER");
        HttpSession session = se.getSession();
        finalizeUserSessionLog(session);
    }
    /**
     * Utility method to finalize user's session log entry. Returns 
     * early if the session log isn't found or more than one is returned.
     * @param session 
     */
    private void finalizeUserSessionLog(HttpSession session) {
        String sessionId = session.getId();
        LogoutReasonType logoutReason = (LogoutReasonType) session.getAttribute("logoutreason");
        if (logoutReason == null) {
            logoutReason = LogoutReasonType.SESSION_TIMEOUT;
        }
        try {
            sessionData = sessionLogger.findBySessionId(sessionId);
        } catch (NonexistentEntityException | UnexpectedResultSetSizeException ex) {
            logger.log(Level.WARNING, " sessionDestroyed ", ex);
            return;
        }
        Calendar now = ts.getUtcDateTimeAsCalendar();
        sessionData.setLogoutTimestamp(now);
        sessionData.setLogoutReason(logoutReason);
        sessionLogger.update(sessionData);
    }
}

如果这对您有帮助。。。

在我们的应用程序中,我们扩展了HttpSessionListener,并使用sessionDestroyed方法来记录会话超时事件。

并在CCD_ 3中注册为

<listener>
    <listener-class>
        com.ourpackage.OurHttpSessionListener
    </listener-class>
</listener>

我相信您只能通过servlet过滤器捕获servlet容器的事件。PhaseListener只存在于JSF"会话"中,在servlet请求之后。检查JSF的生命周期以确保。之后,您可以在JSF 中创建另一个使"会话"无效的请求

最新更新