【问题标题】:How to differentiate between the session timeout by the Tomcat container and logout link press by the user?如何区分Tomcat容器的会话超时和用户的注销链接?
【发布时间】:2025-12-27 16:30:07
【问题描述】:

有没有办法区分 Tomcat容器会话超时用户按下的注销链接强>?

EDIT1:我的环境详细信息:Java 1.8Apache Tomcat 8.0.36 Windows服务器 2012

我有一个实现javax.servlet.http.HttpSessionListenerMyHttpSessionListener

public class MyHttpSessionListener implements HttpSessionListener {         
    @Override
    public void sessionCreated(HttpSessionEvent httpSessionEvent) {
        System.out.println(httpSessionEvent.getSession().getId()+" was CREATED");
    }

    @Override
    public void sessionDestroyed(HttpSessionEvent httpSessionEvent) {
        System.out.println(httpSessionEvent.getSession().getId()+" was DESTROYED");
    }
}

以及web.xml 文件中的相应配置声明

<listener>
    <listener-class>com.webapp.listeners.MyHttpSessionListener</listener-class>
</listener>

我的 web 应用程序没有使用 Spring Security

【问题讨论】:

    标签: spring spring-mvc session tomcat httpsession


    【解决方案1】:

    HttpSessionListener 将在 Servlet 级别处理它。这里一个重要的问题是您使用的是哪个应用程序/Web 服务器? 你需要看看SessionDeletedEvent and SessionExpiredEvent
    现在试试SessionDestroyedEvent

    @Component
    public class SessionEndedListener implements ApplicationListener<SessionDestroyedEvent> {
    
        @Override
        public void onApplicationEvent(SessionDestroyedEvent event)
        {
            for (SecurityContext securityContext : event.getSecurityContexts())
            {
                Authentication authentication = securityContext.getAuthentication();
                YourPrincipalClass user = (YourPrincipalClass) authentication.getPrincipal();
                // do something
            }
        }
    
    }
    

    你还需要在web.xml注册这个

    <listener>
        <listener-class>
            org.springframework.security.web.session.HttpSessionEventPublisher
        </listener-class>
    </listener>
    

    更新答案
    在最近的编辑之后,现在对于这种情况,您需要使用

    HttpSessionBindingListener
    


    当从会话中删除对象时调用它(通过HTTPSessionremoveAttribute() 方法或通过会话的失效/过期显式调用)。

    【讨论】:

    • Thanx Khan (@Freak) 回复,我没有为我的应用程序使用 Spring Security。有没有办法以普通的Servlets 检测会话超时的来源?已在上面的 EDIT1 中更新了我的环境详细信息。
    • 您在编辑之前不清楚您的问题,并且您有一个 Spring-MVC 标签,所以我认为您可能正在寻找 Spring 中的一些解决方案
    • @Shiva 看看更新的答案
    【解决方案2】:

    你可以解析会话 lastAccessTime,如果是前一段时间(配置的过期时间),那么它就过期了。

    【讨论】: