简介:

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 对比
对比项SessionCookie
存储位置服务器内存客户端浏览器
安全性高(数据不暴露给客户端)低(可被查看/篡改)
存储大小无明显限制≤ 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编程工具,助力开发者即刻编程。

更多推荐