简介:

HttpSession 是 Java Web 中用于在服务器端保存用户会话数据的核心接口,由 Servlet 容器(如 Tomcat)负责创建和管理。


一、获取 Session
// 有则获取,无则创建(最常用)
HttpSession session = request.getSession();

// 有则获取,无则返回 null(不创建新的)
HttpSession session = request.getSession(false);

// 等价于 getSession(),有则获取,无则创建
HttpSession session = request.getSession(true);
二、常用方法
方法 说明
getId() 获取 Session 的唯一 ID(JSESSIONID)
setAttribute(String name, Object value) 存入数据
getAttribute(String name) 读取数据,返回 Object
removeAttribute(String name) 删除某个属性
getAttributeNames() 获取所有属性名
setMaxInactiveInterval(int seconds) 设置最大不活跃时间(秒)
getMaxInactiveInterval() 获取最大不活跃时间
invalidate() 销毁 Session(登出时用)
isNew() 是否是新创建的 Session
getCreationTime() 创建时间(毫秒时间戳)
getLastAccessedTime() 最后访问时间

三、基本操作示例

存入数据:

HttpSession session = request.getSession();
session.setAttribute("user", "zhangsan");
session.setAttribute("role", "admin");
session.setMaxInactiveInterval(30 * 60); // 30分钟超时

读取数据:

HttpSession session = request.getSession(false);
if (session != null) {
    String user = (String) session.getAttribute("user");
    String role = (String) session.getAttribute("role");
    System.out.println("用户:" + user + ",角色:" + role);
}

删除单个属性:

session.removeAttribute("role");

销毁 Session(退出登录):

HttpSession session = request.getSession(false);
if (session != null) {
    session.invalidate(); // 立即销毁,所有数据清空
}
四、Session 超时配置

方式一:代码中设置(单个 Session)

session.setMaxInactiveInterval(1800); // 1800秒 = 30分钟
session.setMaxInactiveInterval(-1);   // -1 表示永不超时

方式二:web.xml 全局配置(分钟为单位)

<session-config>
    <session-timeout>30</session-timeout> <!-- 单位:分钟 -->
</session-config>

注意:web.xml 中的 session-timeout 单位是分钟,而 setMaxInactiveInterval() 单位是,切勿混淆。

五、Session 工作原理

第一次请求                         后续请求
┌──────────┐  请求(无Cookie)   ┌──────────────┐
│  Browser │ ─────────────────→ │    Server    │
│          │                    │  创建Session  │
│          │ ←───────────────── │  生成唯一ID  │
│          │  Set-Cookie:        └──────────────┘
│          │  JSESSIONID=abc123
│          │
│          │  请求(携带Cookie)  ┌──────────────┐
│          │ ─────────────────→ │    Server    │
│          │  Cookie:            │ 根据ID查找   │
│          │  JSESSIONID=abc123  │  Session对象 │
└──────────┘ ←───────────────── └──────────────┘
                响应数据

Session 的本质:服务器用 JSESSIONID 这个 Cookie 来关联客户端与服务端的 Session 对象。

六、典型应用:登录登出

LoginServlet.java(登录):

@WebServlet("/login")
public class LoginServlet extends HttpServlet {
    @Override
    protected void doPost(HttpServletRequest req, HttpServletResponse resp)
            throws ServletException, IOException {

        req.setCharacterEncoding("UTF-8");
        String username = req.getParameter("username");
        String password = req.getParameter("password");

        // 模拟验证(实际应查询数据库)
        if ("admin".equals(username) && "123456".equals(password)) {
            HttpSession session = req.getSession();
            session.setAttribute("loginUser", username);
            session.setAttribute("loginTime", System.currentTimeMillis());
            session.setMaxInactiveInterval(30 * 60); // 30分钟

            resp.sendRedirect(req.getContextPath() + "/dashboard");
        } else {
            resp.sendRedirect(req.getContextPath() + "/login.jsp?error=1");
        }
    }
}

LogoutServlet.java(退出):

@WebServlet("/logout")
public class LogoutServlet extends HttpServlet {
    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp)
            throws ServletException, IOException {

        HttpSession session = req.getSession(false);
        if (session != null) {
            session.invalidate(); // 销毁 Session
        }
        resp.sendRedirect(req.getContextPath() + "/login.jsp");
    }
}

登录检查过滤器(Filter):

@WebFilter("/*")
public class LoginFilter implements Filter {
    // 不拦截的路径
    private static final List<String> EXCLUDED = Arrays.asList(
        "/login", "/login.jsp", "/css/", "/js/"
    );

    @Override
    public void doFilter(ServletRequest req, ServletResponse resp, FilterChain chain)
            throws IOException, ServletException {

        HttpServletRequest request = (HttpServletRequest) req;
        HttpServletResponse response = (HttpServletResponse) resp;

        String uri = request.getRequestURI();
        boolean excluded = EXCLUDED.stream().anyMatch(uri::contains);

        if (excluded) {
            chain.doFilter(req, resp); // 放行
            return;
        }

        HttpSession session = request.getSession(false);
        if (session != null && session.getAttribute("loginUser") != null) {
            chain.doFilter(req, resp); // 已登录,放行
        } else {
            response.sendRedirect(request.getContextPath() + "/login.jsp");
        }
    }
}
七、Session 与 Cookie 对比
对比项 Session Cookie
存储位置 服务器内存 客户端浏览器
安全性 高(数据不暴露给客户端) 低(可被查看/篡改)
存储大小 无明显限制 ≤ 4KB
存储类型 任意 Java 对象 只能是字符串
生命周期 默认30分钟不活跃后销毁 由 maxAge 控制
依赖 依赖 Cookie 传递 JSESSIONID 独立
适用场景 登录状态、权限、购物车 记住用户名、偏好

八、注意事项
  • 禁用 Cookie 的情况:若用户禁用 Cookie,JSESSIONID 无法通过 Cookie 传递,可用 URL 重写:response.encodeURL("/dashboard") 会自动在 URL 后追加 ;jsessionid=xxx
  • 分布式环境:多台服务器时,Session 默认存在单机内存,需改用 Redis 等集中存储(Spring Session)。
  • Session 不是线程安全的:同一 Session 被多个请求并发访问时需注意同步。
  • 及时销毁:登出时务必调用 invalidate(),避免 Session 泄漏。


Logo

汇聚全球AI编程工具,助力开发者即刻编程。

更多推荐