杰瑞科技汇

Java session超时时间如何正确设置?

我将从几个层面详细解释如何设置 Session 的生命周期,包括:

Java session超时时间如何正确设置?-图1
(图片来源网络,侵删)
  1. web.xml 中设置(传统方式)
  2. 在代码中动态设置(编程方式)
  3. 在 Spring Boot 中设置(现代主流方式)
  4. 重要概念:超时时间 vs. 最大不活动时间
  5. Session 何时会失效?

web.xml 中设置(Servlet 3.0 之前)

这是最传统和标准的方式,通过配置部署描述符文件 web.xml 来设置,这种方式设置的是 Session 的最大不活动时间

参数: <session-config><session-timeout>

  • <session-timeout>: 单位是分钟,如果用户在这个时间间隔内没有对 Session 进行任何操作(即没有请求),服务器就会使该 Session 失效。

示例:

<?xml version="1.0" encoding="UTF-8"?>
<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 的最大不活动时间为 30 分钟。
        30 分钟内用户没有任何请求,Session 将被销毁。
    -->
    <session-config>
        <session-timeout>30</session-timeout>
    </session-config>
</web-app>

注意:

Java session超时时间如何正确设置?-图2
(图片来源网络,侵删)
  • <session-timeout> 设置为 0 或负数,Session 将永远不会超时。这通常不推荐,因为它可能导致服务器内存泄漏。
  • Tomcat 的默认值通常是 30 分钟。

在代码中动态设置(编程方式)

你可以在 Servlet 或任何可以获取到 HttpSession 对象的代码中,动态地设置或获取 Session 的超时时间。

核心方法:

  • session.setMaxInactiveInterval(int interval): 设置 Session 的超时时间。
  • session.getMaxInactiveInterval(): 获取当前 Session 的超时时间。

参数: interval 的单位是

示例:

Java session超时时间如何正确设置?-图3
(图片来源网络,侵删)

在一个 Servlet 中:

import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
import java.io.IOException;
@WebServlet("/sessionExample")
public class SessionExampleServlet extends HttpServlet {
    @Override
    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        // 1. 获取或创建 Session
        HttpSession session = request.getSession();
        // 2. 获取并打印当前的 Session 超时时间(单位:秒)
        int currentTimeout = session.getMaxInactiveInterval();
        System.out.println("Current session timeout (seconds): " + currentTimeout);
        // 3. 动态设置 Session 超时时间为 1 小时(3600 秒)
        // 这个设置会覆盖 web.xml 中的全局设置,但只对当前 Session 有效
        session.setMaxInactiveInterval(3600); 
        System.out.println("New session timeout has been set to 1 hour for this session.");
        // 4. 在 Session 中存储一个属性
        session.setAttribute("user", "John Doe");
        response.getWriter().println("Session timeout has been set dynamically.");
    }
}

特点:

  • 这种方式的优先级高于 web.xml 中的全局设置,它只对当前这个特定的 HttpSession 对象生效。
  • 适用于需要根据不同用户、不同业务场景动态调整 Session 生命周期的场景。

在 Spring Boot 中设置(现代主流方式)

Spring Boot 极大地简化了配置,通常不再使用 web.xml,它提供了多种灵活的方式来配置 Session。

Spring Boot 默认使用内嵌的 Servlet 容器(如 Tomcat),并且默认的 Session 超时时间是 30 分钟

application.propertiesapplication.yml 中全局设置

这是最推荐的方式,简单且集中。

application.properties 中: 单位是分钟

# 设置 Session 超时时间为 45 分钟
server.servlet.session.timeout=45m

application.yml 中:

server:
  servlet:
    session:
      timeout: 45m # 也可以写成 45

使用 application.properties@Bean 自定义 SessionRepository

如果你需要更高级的配置,比如使用 Redis 来管理 Session,你需要自定义 SessionRepository

application.properties 中启用 Redis Session:

# 启用 Spring Session 和 Redis 存储
spring.session.store-type=redis
# Redis 连接配置
spring.redis.host=localhost
spring.redis.port=6379
# Session 在 Redis 中的超时时间,单位是毫秒
spring.session.timeout=1800000 # 30分钟,单位是毫秒

在 Java 配置类中设置

你也可以通过一个配置类来设置,这种方式更灵活,可以结合其他逻辑。

import org.springframework.boot.web.servlet.server.Session;
import org.springframework.boot.web.servlet.ServletContextInitializer;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import javax.servlet.ServletContext;
@Configuration
public class SessionConfig {
    // 方式一:通过 ServletContextInitializer
    @Bean
    public ServletContextInitializer servletContextInitializer() {
        return servletContext -> {
            // 设置 Session 超时时间为 20 分钟
            servletContext.setSessionTimeout(20); // 单位是分钟
        };
    }
    // 方式二:直接配置 ServerProperties (更推荐)
    // Spring Boot 会自动扫描这个 Bean 并应用配置
    /*
    @Bean
    public ServerProperties serverProperties() {
        ServerProperties properties = new ServerProperties();
        properties.getServlet().setSessionTimeout(Duration.ofMinutes(20));
        return properties;
    }
    */
}

注意: 在 Spring Boot 中,application.properties 中的配置通常比 Java 配置类中的 @Bean 优先级更高。


重要概念:超时时间 vs. 最大不活动时间

在 Java Servlet 规范中,这两个概念指的是同一个东西,即 <session-timeout>

  • 含义:这是 Session 的最大不活动时间
  • 计时器:计时器从最后一次客户端请求开始计时,如果在这个时间间隔内,客户端没有发送任何新的请求,服务器就会认为该 Session 已经失效,并将其从内存中移除。
  • 不是 Session 的总生命周期:它不是从 Session 创建开始计算的固定时长,只要用户在超时前有活动,Session 就会一直存在。

你设置了超时时间为 30 分钟。

  • 用户登录,Session 创建。
  • 用户在第 25 分钟时点击了一个链接,刷新了页面。
  • Session 的计时器会重置,新的 30 分钟计时开始。
  • 如果用户在第 35 分钟(从登录开始算)没有任何操作,那么在第 50 分钟(登录后 25 + 30)时,Session 就会失效。

Session 何时会失效?

除了因为不活动而超时外,Session 还会在以下情况下失效:

  1. 调用 invalidate() 方法: 这是最明确的方式,通常用于用户主动“退出登录”。

    HttpSession session = request.getSession();
    session.invalidate(); // 立即销毁当前 Session
  2. 服务器关闭或重启: 内存中的 Session 会随着服务器进程的结束而丢失,如果使用了像 Redis 这样的外部存储,Session 数据可以保留。

  3. Session 过期: 如上所述,超过了 maxInactiveInterval 时间。

  4. 浏览器关闭: 这是一个常见的误解。默认情况下,关闭浏览器并不会使服务器端的 Session 立即失效。

    • 服务器端的 Session 仍然存在,并会一直等到其超时。
    • 当用户再次打开浏览器并访问该网站时,浏览器通常不会再发送之前的 JSESSIONID cookie(除非浏览器配置了“保持登录”或使用了“记住我”功能)。
    • 服务器会认为这是一个新的会话,并创建一个新的 Session。
方式 配置位置 单位 作用域 备注
web.xml web.xml 分钟 全局 传统方式,Servlet 规范标准
代码设置 Java 代码 当前 Session 动态、灵活,优先级高于 web.xml
Spring Boot application.properties 分钟 或 ms 全局 推荐的现代方式,简洁
Spring Boot (Redis) application.properties 毫秒 全局 用于分布式 Session 管理

最佳实践建议:

  • 对于传统的 Java Web 项目,优先使用 web.xml 进行全局配置,特殊场景下在代码中动态覆盖。
  • 对于 Spring Boot 项目,优先使用 application.propertiesapplication.yml 进行配置,这是最清晰、最符合 Spring Boot 设计理念的方式。
  • 如果你的应用是微服务架构或者需要多实例共享 Session,请务必使用 Spring Session + Redis 等外部存储方案,并在配置文件中设置超时时间。
分享:
扫描分享到社交APP
上一篇
下一篇