Skip to content

05-会话技术(Cookie / Session)

对应原始资料:day07-会话技术

一、为什么需要会话技术

HTTP 是无状态协议,服务器记不住"这个用户登录过"。会话技术用来在一次会话(打开浏览器到关闭)中多次请求间共享数据

技术存储位置大小限制安全性
Cookie客户端(浏览器)单个 4KB,站点约 20 个低(用户可改)
Session服务端(内存)无明显限制

二、Cookie

1. 创建与发送

java
Cookie c = new Cookie("username", "tom");
c.setMaxAge(60 * 60 * 24);   // 存活 1 天(秒),不设则浏览器关闭即销毁
c.setPath("/");               // 全站可用
resp.addCookie(c);

2. 获取

java
Cookie[] cookies = req.getCookies();
if (cookies != null) {
    for (Cookie c : cookies) {
        if ("username".equals(c.getName())) {
            String val = c.getValue();
        }
    }
}

3. 删除 / 修改

java
// 修改:同名再发一次
Cookie c = new Cookie("username", "newVal");
resp.addCookie(c);
// 删除:把存活时间设为 0
c.setMaxAge(0);
resp.addCookie(c);

4. 应用场景

  • "记住我"自动登录(保存 token)。
  • 浏览历史、最近搜索。
  • 网站个性化偏好(语言、主题)。

5. 注意事项

  • Cookie 不能直接存中文(可 URL 编码后存)。
  • 不同浏览器之间不共享。
  • HttpOnly 防止 JS 读取,Secure 仅 HTTPS 传输。

三、HttpSession(重点)

1. 获取 Session

java
HttpSession session = req.getSession();    // 没有就创建
  • Session 域对象比 ServletContext 小,比 request 大,一次会话内共享

2. 存取数据

java
session.setAttribute("user", user);
Object u = session.getAttribute("user");
session.removeAttribute("user");

3. 销毁

  • 默认 30 分钟不操作自动销毁(web.xmlsession.setMaxInactiveInterval(60))。
  • 手动:session.invalidate();
  • 服务器重启。

4. 登录案例(经典)

java
// 登录成功后
HttpSession session = req.getSession();
session.setAttribute("user", user);

// 其他页面/Servlet 判断登录
Object user = req.getSession().getAttribute("user");
if (user == null) {
    resp.sendRedirect("/login.html");
    return;
}

5. Session 销毁时机

  • 会话:一次会话 = 一个浏览器进程(关闭浏览器后,JSESSIONID Cookie 消失,但服务端 Session 仍存在直到超时)。
浏览器第一次访问 → 服务器创建 Session → 返回 JSESSIONID Cookie

浏览器后续请求带 JSESSIONID → 服务器据此找到对应 Session

Session 依赖 Cookie 中的 JSESSIONID 来识别。如果浏览器禁用 Cookie,需用 URL 重写(resp.encodeURL())。

五、三大域对象对比

域对象范围典型场景
HttpServletRequest一次请求转发间传数据
HttpSession一次会话登录态、购物车
ServletContext整个应用全局配置、在线人数

六、JSP(了解)

JSP(Java Server Pages)是 Java 的"模板引擎",本质是一个 Servlet,能在 HTML 中嵌入 Java 代码。

jsp
<%@ page contentType="text/html;charset=UTF-8" %>
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
<ul>
  <c:forEach items="${list}" var="u">
    <li>${u.name}</li>
  </c:forEach>
</ul>

现代前后端分离已很少用 JSP,但老项目仍可能遇到,了解即可。

练习建议

  1. 实现登录 + "记住我"(Cookie 存用户名一周)。
  2. 实现登录拦截(Session 判断)。
  3. 用 Session 实现简易购物车。
  4. 统计网站在线人数(ServletContext + Listener)。