核心概念:Session 是什么?
简单回顾一下 Session,Session 是一种在服务器端存储用户特定数据的机制,当用户访问网站时,服务器会创建一个唯一的 Session ID,并将其发送给客户端(通常通过 Cookie 存储),之后,客户端每次请求都会携带这个 Session ID,服务器通过它来识别用户,并获取与之关联的 Session 数据。

Session 过期指的是在一定时间内,如果没有用户活动,这个 Session 及其存储的数据就会被服务器销毁,用户需要重新登录或重新建立会话。
Web 应用层面 (Servlet API)
在标准的 Java Web 开发中,我们通常使用 HttpSession 对象来管理会话,其过期时间的配置主要有两种方式:
在 web.xml 中全局配置 (推荐)
这是最传统和标准的方式,为整个 Web 应用设置一个默认的 Session 超时时间。
在 WEB-INF/web.xml 文件中添加以下 <session-config> 节点:

<web-app xmlns="http://xmlns.jcp.org/xml/ns/javaee"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_4_0.xsd"
version="4.0">
<!-- ... 其他配置 ... -->
<session-config>
<!-- 设置 Session 超时时间,单位为分钟 -->
<!-- 设置为 30 分钟 -->
<session-timeout>30</session-timeout>
</session-config>
</web-app>
关键点:
- 单位:
<session-timeout>的值是以 分钟 为单位的。 - 默认值:如果未配置,大多数 Servlet 容器(如 Tomcat)的默认值是 30 分钟。
- 作用范围:这个配置是全局的,作用于该 Web 应用下的所有 Session。
- 如何设置永不超时:将值设置为
0或负数(如-1)。注意:0在某些容器(如 Tomcat 7+)中可能被解释为使用默认值,而-1是明确表示永不超时的标准做法,但通常不推荐使用永不超时,这可能导致服务器内存泄漏。
在代码中动态设置
你可以在 Java 代码中为某个特定的 HttpSession 对象单独设置超时时间。
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpSession;
// 在 Servlet 或 Controller 中获取 request 对象
HttpSession session = request.getSession();
// 设置 Session 超时时间,单位是秒
// 设置为 10 分钟 (600 秒)
session.setMaxInactiveInterval(600);
// 获取当前 Session 的超时时间(单位:秒)
int timeout = session.getMaxInactiveInterval();
System.out.println("Current session timeout in seconds: " + timeout);
关键点:
- 单位:
setMaxInactiveInterval(int interval)的值是以 秒 为单位的,这一点与web.xml中的配置不同,需要特别注意! - 优先级:代码中的动态设置会覆盖
web.xml中的全局设置。 - 影响范围:只对当前这个
session对象有效。
框架层面 (Spring Session)
在现代 Java Web 应用中,尤其是基于 Spring Boot 的项目,我们更倾向于使用 Spring Session,它提供了比原生 Servlet Session 更强大、更灵活的功能,

- 支持集群:可以将 Session 数据存储在 Redis、Hazelcast、JDBC 数据库等外部存储中,实现多台服务器间的 Session 共享。
- 多种客户端支持:除了 Cookie,还支持 URL 重写等方式来传递 Session ID。
- API 一致性:无论后端存储如何变化,你使用的 Java API 仍然是
HttpSession,代码改动很小。
Spring Session 的过期时间配置通常与选定的后端存储紧密相关。
使用 Redis 作为 Session 存储器 (最常见)
这是生产环境中最主流的方案,配置分为两步:
第1步:在 application.properties 或 application.yml 中配置 Spring Session 和 Redis
# application.properties # 1. 配置 Session 过期时间 (单位: 毫秒) # 设置为 30 分钟 spring.session.timeout=1800000 # 2. (可选) 配置 Redis 中 Session 的 key 的前缀 spring.session.redis.namespace=spring:session # 3. (可选) 配置 Redis 的连接信息 spring.redis.host=localhost spring.redis.port=6379
第2步:添加 Spring Session 和 Redis 的依赖
<!-- pom.xml -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-redis</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.session</groupId>
<artifactId>spring-session-data-redis</artifactId>
</dependency>
关键点:
- 单位:
spring.session.timeout的单位是 毫秒,这是最容易出错的地方! - 工作原理:Spring Session 会在 Redis 中为每个 Session 创建一个 Hash 结构,它会创建一个带有过期时间的 Key(
spring:session:expirations:1678886400000),这个 Key 到期后,Redis 会自动删除所有相关的 Session Hash,这种机制被称为 "被动过期"。 - 与原生 Session 的关系:即使你配置了 Spring Session,
web.xml中的<session-timeout>和session.setMaxInactiveInterval()仍然可以工作,Spring Session 内部会监听这些变化,并同步更新 Redis 中的过期时间,但最佳实践是统一使用spring.session.timeout进行配置。
使用内存存储 (仅用于开发/测试)
如果你没有使用 Redis 等外部存储,Spring Session 默认会将数据存在应用内存中。
# application.properties # 配置 Session 过期时间 (单位: 秒) # 设置为 30 分钟 server.servlet.session.timeout=1800
注意:在这种情况下,配置项是 server.servlet.session.timeout,单位是 秒。
总结与最佳实践
| 配置方式 | 位置/文件 | 单位 | 作用范围 | 备注 |
|---|---|---|---|---|
| Servlet (全局) | web.xml |
分钟 | 整个 Web 应用 | 传统方式,简单直接。 |
| Servlet (动态) | Java 代码 (setMaxInactiveInterval) |
秒 | 当前 Session 对象 | 灵活,可覆盖全局配置。 |
| Spring Session (Redis) | application.properties (spring.session.timeout) |
毫秒 | 整个 Spring Boot 应用 | 强烈推荐,适用于生产环境,支持集群。 |
| Spring Session (内存) | application.properties (server.servlet.session.timeout) |
秒 | 整个 Spring Boot 应用 | 仅适用于开发和单机测试。 |
最佳实践建议:
- 优先使用框架配置:在 Spring Boot 项目中,始终使用
application.properties或application.yml来配置 Session 超时时间,不要混用web.xml和 Spring Boot 的配置,以避免不必要的混乱。 - 明确单位:配置时务必注意单位(分钟、秒、毫秒),这是最常见的错误来源。
- 为生产环境选择合适的存储:如果应用需要水平扩展(多台服务器),必须使用 Spring Session + Redis (或类似中间件),绝对不要依赖单机内存中的 Session。
- 考虑用户体验:设置合理的超时时间,太短(如 5 分钟)会频繁让用户重新登录,体验差;太长(如几小时)会增加安全风险和服务器内存压力,30 分钟是一个比较通用的折中选择。
- 提供“记住我”功能:对于需要长时间保持登录状态的场景,提供一个“记住我”(Remember Me)的复选框是更好的做法,这通常通过生成一个长期有效的 Token(如使用 JWT 或 Spring Security 的 Remember Me 机制)来实现,而不是无限期延长 Session 的生命周期。
