杰瑞科技汇

Java session过期时间如何设置与调整?

核心概念:Session 是什么?

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

Java session过期时间如何设置与调整?-图1
(图片来源网络,侵删)

Session 过期指的是在一定时间内,如果没有用户活动,这个 Session 及其存储的数据就会被服务器销毁,用户需要重新登录或重新建立会话。


Web 应用层面 (Servlet API)

在标准的 Java Web 开发中,我们通常使用 HttpSession 对象来管理会话,其过期时间的配置主要有两种方式:

web.xml 中全局配置 (推荐)

这是最传统和标准的方式,为整个 Web 应用设置一个默认的 Session 超时时间。

WEB-INF/web.xml 文件中添加以下 <session-config> 节点:

Java session过期时间如何设置与调整?-图2
(图片来源网络,侵删)
<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 更强大、更灵活的功能,

Java session过期时间如何设置与调整?-图3
(图片来源网络,侵删)
  • 支持集群:可以将 Session 数据存储在 Redis、Hazelcast、JDBC 数据库等外部存储中,实现多台服务器间的 Session 共享。
  • 多种客户端支持:除了 Cookie,还支持 URL 重写等方式来传递 Session ID。
  • API 一致性:无论后端存储如何变化,你使用的 Java API 仍然是 HttpSession,代码改动很小。

Spring Session 的过期时间配置通常与选定的后端存储紧密相关。

使用 Redis 作为 Session 存储器 (最常见)

这是生产环境中最主流的方案,配置分为两步:

第1步:在 application.propertiesapplication.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 应用 仅适用于开发和单机测试。

最佳实践建议:

  1. 优先使用框架配置:在 Spring Boot 项目中,始终使用 application.propertiesapplication.yml 来配置 Session 超时时间,不要混用 web.xml 和 Spring Boot 的配置,以避免不必要的混乱。
  2. 明确单位:配置时务必注意单位(分钟、秒、毫秒),这是最常见的错误来源。
  3. 为生产环境选择合适的存储:如果应用需要水平扩展(多台服务器),必须使用 Spring Session + Redis (或类似中间件),绝对不要依赖单机内存中的 Session。
  4. 考虑用户体验:设置合理的超时时间,太短(如 5 分钟)会频繁让用户重新登录,体验差;太长(如几小时)会增加安全风险和服务器内存压力,30 分钟是一个比较通用的折中选择。
  5. 提供“记住我”功能:对于需要长时间保持登录状态的场景,提供一个“记住我”(Remember Me)的复选框是更好的做法,这通常通过生成一个长期有效的 Token(如使用 JWT 或 Spring Security 的 Remember Me 机制)来实现,而不是无限期延长 Session 的生命周期。
分享:
扫描分享到社交APP
上一篇
下一篇