使用HttpSessionListener时Session超时异常问题咨询
首先明确:Session超时的正常机制是基于最后一次活跃时间的——只要在超时窗口内(比如你设置的1分钟)有携带该Session ID的请求到达服务器,服务器就会重置Session的超时计时器,不会触发销毁。你遇到的“无论是否发起请求都会销毁”肯定是异常情况,大概率是请求没有正确关联到已有的Session,或者代码/配置存在问题。
排查方向
1. 前端请求是否正确携带Session ID
默认情况下,Servlet的Session是通过JSESSIONID Cookie来传递的,你需要确认:
- 前端请求是否包含
JSESSIONIDCookie?可以通过浏览器开发者工具的网络面板查看请求头里的Cookie字段。 - 如果是前后端分离的跨域场景,是否配置了允许携带Cookie?比如前端请求要设置
withCredentials: true,后端要配置CORS允许credentials。如果没做这些,每次请求都会创建新Session,旧Session到时间就会被销毁,看起来像是“原有Session不管请求都销毁”。
2. 检查SessionListener代码的问题
你的sessionDestroyed方法里调用了httpSession.invalidate(),这是完全多余的——sessionDestroyed是Session即将被销毁时的回调方法,此时容器已经在处理Session销毁流程,手动调用invalidate()不会有正面作用,反而可能引发未知问题,建议删掉这行代码。
另外,你的遍历删除UserService中用户记录的逻辑存在索引越界风险:当你删除集合中的元素后,后续的索引会错位,可能导致漏删或者数组越界。可以改成更安全的写法:
if (!userService.getUser().isEmpty()) { userService.getUser().removeIf(user -> user.getSessionId().equals(httpSession.getId())); }
3. 确认配置是否被覆盖
检查是否有其他配置覆盖了server.servlet.session.timeout:
- 比如Tomcat的
context.xml中是否配置了<session-config>标签,里面的session-timeout优先级可能高于Spring Boot的配置? - 代码中是否通过
@Configuration类手动配置了Session超时时间?
4. 验证Session的活跃状态
可以在sessionCreated方法中记录Session的创建时间,然后在每次请求的Controller中打印Session的最后访问时间httpSession.getLastAccessedTime(),对比是否和请求时间一致,以此确认请求是否真的触发了Session的活跃时间重置。
总结
最可能的原因是前端请求没有正确携带Session ID,导致服务器无法识别已有Session,每次请求都新建Session,旧Session到时间自然销毁。先排查Cookie传递的问题,再逐步验证其他可能性。
内容的提问来源于stack exchange,提问作者LazyCoder

