在 Java Web 開發中,會話管理是實現用戶狀態追蹤的關鍵機制。主要分為兩大技術體系:Cookie(客戶端存儲)與 HttpSession(服務端存儲)。兩者各有優劣,適用場景不同,掌握其核心原理與應用細節,對於構建安全、高效的 Web 應用至關重要。
Cookie 類用於封裝會話數據,主要操作包括:
new Cookie(String name, String value)setPath(String uri):定義 Cookie 的有效訪問路徑setMaxAge(int expiry):設置生存時間(秒)setValue(String newValue):更新 Cookie 值response.addCookie(Cookie cookie):將 Cookie 寫入響應頭request.getCookies():從請求頭獲取 Cookie 數組Set-Cookie 響應頭發送給瀏覽器Cookie 請求頭setPath("/test") 表示僅在 /test 路徑下攜帶 Cookie@WebServlet("/CookieDemo")
public class CookieDemo extends HttpServlet {
protected void doGet(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
Cookie cookie = new Cookie("name", "shutu008");
cookie.setPath("/test"); // 指定有效路徑
cookie.setMaxAge(1000); // 1000 秒有效期
response.addCookie(cookie); // 發送至瀏覽器
}
}
@WebServlet("/CookieTest")
public class CookieTest extends HttpServlet {
protected void doGet(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
Cookie[] cookies = request.getCookies();
if (cookies != null) {
for (Cookie c : cookies) {
response.getWriter().write(c.getName() + "=" + c.getValue() + "
");
}
}
}
}
getSession() / getSession(true):獲取或創建getSession(false):僅獲取,不存在返回 nullsetAttribute(String name, Object value)getAttribute(String name)removeAttribute(String name)setMaxInactiveInterval(int seconds):設置超時時間(秒)invalidate():手動銷毀getId():獲取唯一標識 JSESSIONID服務端為每個 Session 生成唯一 ID(JSESSIONID),默認通過 Cookie 交換:
Set-Cookie: JSESSIONID=xxxCookie: JSESSIONID=xxx不同瀏覽器/窗口持有不同 JSESSIONID,實現會話隔離。
<session-config>
<session-timeout>30</session-timeout> <!-- 分鐘 -->
</session-config>
Cookie c = new Cookie("JSESSIONID", session.getId());
c.setMaxAge(60 * 60); // 1小時
response.addCookie(c);
@WebServlet("/HttpSessionDemo")
public class HttpSessionDemo extends HttpServlet {
protected void doGet(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
response.setContentType("text/html;charset=UTF-8");
HttpSession session = request.getSession();
// 存儲數據
session.setAttribute("name", "srv");
session.setAttribute("phone", "051112345678");
// 遍歷輸出
Enumeration names = session.getAttributeNames();
while (names.hasMoreElements()) {
String name = names.nextElement();
response.getWriter().write(name + "=" + session.getAttribute(name) + "
");
}
// 判斷新舊會話
if (session.isNew()) {
response.getWriter().write("新會話 ID: " + session.getId());
} else {
response.getWriter().write("現有會話 ID: " + session.getId());
}
session.setMaxInactiveInterval(60); // 1分鐘超時
}
}
| 維度 | Cookie | HttpSession |
|---|---|---|
| 存儲位置 | 客戶端 | 服務端 |
| 安全性 | 低(可被竄改) | 高(數據不暴露) |
| 容量 | 4KB/個 | 受限於服務端內存 |
| 適用場景 | 輕量級標識、記住登錄 | 敏感數據、購物車、權限狀態 |
最佳實踐:Session 存儲核心業務數據,Cookie 僅存儲 Session ID 或非敏感標識。生產環境建議結合 Redis 實現 Session 共享,支撐集群部署。