在 Java Web 开发中,Session 是维持用户会话状态的核心机制。默认情况下,Tomcat 的 Session 超时时间为 30 分钟,超时后 Session 会自动失效,用户需要重新登录。但在某些特殊场景下,我们可能希望 Session 永不失效。本文将系统梳理 Session 超时时间的四种设置方式,并重点讲解如何实现"永不失效"。
一、为什么需要设置 Session 超时时间?
Session 超时机制的存在,主要是为了:
- 释放服务器资源:避免大量长期不活动的 Session 占用内存。
- 保证安全性:用户长时间未操作时自动退出,降低会话被劫持的风险。
- 控制用户数量:结合监听器可以实现在线用户数的统计与控制。
但有些场景(如内部管理系统、长时间运行的批处理页面、调试环境等),我们希望 Session 保持长期有效,甚至永不失效。
二、Session 超时时间的四种设置方式
方式一:在 Tomcat 的 conf/web.xml 中全局设置
这是 Tomcat 级别的全局配置,作用于所有部署在该 Tomcat 上的 Web 应用。
xml
<session-config>
<session-timeout>30</session-timeout>
</session-config>
- 单位:分钟
- Tomcat 默认值为 30 分钟
- 负数或 0 表示 Session 永不失效
注意:这里的超时时间是以服务器时间为准,而不是客户端时间。调试时请修改服务器时间进行测试。
方式二:在项目的 web.xml 中设置
这是应用级别的配置,只针对当前 Web 项目生效。
xml
<!-- 时间单位为分钟 -->
<session-config>
<session-timeout>15</session-timeout>
</session-config>
- 这里的
15表示 15 分钟后 Session 失效。 - 该配置会覆盖 Tomcat 全局配置。
方式三:在 Java 代码中动态设置
这是最灵活的方式,可以针对具体页面或具体 Session 进行设置。
java
session.setMaxInactiveInterval(30 * 60); // 单位:秒,即 30 分钟
- 单位:秒
- 优先级最高,会覆盖
web.xml中的配置。 - 同样,设置为负数表示永不失效:
java
session.setMaxInactiveInterval(-1); // Session 永不失效
方式四:配置 Tomcat 的 Session 持久化
通过 PersistentManager 可以将 Session 保存到文件或数据库中,即使服务器重启,Session 也能恢复。
文件存储方式
xml
<Manager
className="org.apache.catalina.session.PersistentManager"
saveOnRestart="true"
maxActiveSession="-1"
minIdleSwap="0"
maxIdleSwap="30"
maxIdleBackup="0">
<Store
className="org.apache.catalina.session.FileStore"
checkInterval="60"
directory="../session"/>
</Manager>
数据库存储方式(JDBCStore)
xml
<Store
className="org.apache.catalina.JDBCStore"
driverName="com.mysql.jdbc.Driver"
connectionURL="jdbc:mysql://localhost/tomsessionDB?user=root&password="
sessionTable="tomcat_session"
sessionIdCol="session_id"
sessionDataCol="session_data"
sessionValidCol="session_valid"
sessionMaxInactiveCol="max_inactive"
sessionLastAccessedCol="last_access"
sessionAppCol="app_name"
checkInterval="60"
debug="99" />
常用参数说明:
| 参数 | 说明 |
|---|---|
maxActiveSessions |
可处于活动状态的 Session 数,-1 表示不限制 |
checkInterval |
检查 Session 是否过期的时间间隔,默认 60 秒 |
saveOnRestart |
服务器关闭时是否将所有 Session 保存到文件中 |
minIdleSwap/maxIdleSwap |
Session 处于不活动状态最短/最长时间(秒),转移到 FileStore 中,-1 表示无限制 |
maxIdleBackup |
超过这一时间将 Session 备份,-1 表示无限制 |
directory |
文件存储位置:work\Catalina\host name\web app\session\文件名.session |
三、三种配置方式的优先级
Tomcat 全局 web.xml < 项目 web.xml < Java 代码 setMaxInactiveInterval
优先级从低到高,代码设置的方式优先级最高。
四、如何让 Session 永不失效?
综合以上四种方式,实现 Session 永不失效的方法有以下几种:
方法 1:修改 Tomcat 全局配置
在 tomcat/conf/web.xml 中:
xml
<session-config>
<session-timeout>-1</session-timeout>
</session-config>
或设置为 0:
xml
<session-config>
<session-timeout>0</session-timeout>
</session-config>
方法 2:修改项目 web.xml
xml
<session-config>
<session-timeout>-1</session-timeout>
</session-config>
方法 3:在代码中动态设置(推荐)
java
session.setMaxInactiveInterval(-1); // 永不失效
这种方式最灵活,可以针对特定用户或特定场景单独设置。
五、Session 失效后的监听处理
有时我们需要在 Session 失效后执行一些操作,比如:
- 减少在线用户数
- 清理用户登录状态
- 记录日志
这时可以使用 HttpSessionListener 监听器:
java
public class OnlineUserListener implements HttpSessionListener {
@Override
public void sessionCreated(HttpSessionEvent event) {
HttpSession session = event.getSession();
String id = session.getId() + session.getCreationTime();
SummerConstant.UserMap.put(id, Boolean.TRUE); // 添加用户
}
@Override
public void sessionDestroyed(HttpSessionEvent event) {
HttpSession session = event.getSession();
String id = session.getId() + session.getCreationTime();
synchronized (this) {
SummerConstant.USERNum--; // 用户数减一
SummerConstant.UserMap.remove(id); // 从用户组中移除
}
}
}
在 web.xml 中注册监听器:
xml
<listener>
<listener-class>com.demo.OnlineUserListener</listener-class>
</listener>
注意:如果设置 Session 永不失效,
sessionDestroyed方法将不会因为超时而触发,只会在调用session.invalidate()或服务器关闭时触发。
六、总结对比
| 设置方式 | 作用范围 | 单位 | 永不失效设置 | 优先级 |
|---|---|---|---|---|
Tomcat conf/web.xml |
所有应用 | 分钟 | -1 或 0 |
最低 |
项目 web.xml |
当前应用 | 分钟 | -1 或 0 |
中 |
| Java 代码 | 具体 Session | 秒 | -1 |
最高 |
| Session 持久化 | 服务器重启恢复 | --- | 配合使用 | --- |
七、注意事项
- 永不失效的 Session 会占用服务器内存,用户量大的系统慎用。
- 安全性风险:Session 长期有效会增加会话劫持的风险,建议配合 HTTPS、Token 刷新等机制。
- 服务器重启:如果未配置 Session 持久化,服务器重启后 Session 仍会丢失。
- 调试技巧 :测试超时时间时,请修改服务器时间,而非客户端时间。
八、结语
Session 超时时间的设置是 Java Web 开发中的基础技能,掌握这四种方式及其优先级,能够帮助我们在不同场景下灵活应对。而在需要"永不失效"的特殊场景中,通过 setMaxInactiveInterval(-1) 或 web.xml 中设置 -1 即可轻松实现。
最后提醒一句:Session 永不失效是一把双刃剑,请根据实际业务需求谨慎使用。
本文基于 Tomcat 7.0+ 环境整理