「Session」是計算機科學中最容易產生歧義的詞彙之一,按上下文至少有六種含義:
Map<String, Object>)。javax.servlet.http.HttpSession)。本文聚焦於第 4、5、6 種含義。
JSESSIONID。Set-Cookie: JSESSIONID=xxx; Path=/ 發送給瀏覽器。jsessionid 附加到所有 URL:/app/home;jsessionid=xxx。response.encodeURL(url) / encodeRedirectURL(url) 自動處理。利用 SSL 握手建立的 Session ID 作為識別符,安全性高但實現複雜。
// 獲取 Session (true=不存在則創建,false=僅獲取)
HttpSession session = request.getSession(true);
// 存取屬性
session.setAttribute("user", userObj);
User user = (User) session.getAttribute("user");
// 移除屬性
session.removeAttribute("tempData");
// 設置超時 (秒),負數表示永不超時
session.setMaxInactiveInterval(30 * 60); // 30 分鐘
// 獲取會話資訊
String id = session.getId();
long created = session.getCreationTime();
long lastAccessed = session.getLastAccessedTime();
boolean isNew = session.isNew();
// 手動銷毀 (登出)
session.invalidate();
| 問題 | 原因 | 解決方案 |
|---|---|---|
| 屬性丟失/不同請求拿到不同 Session | 多次調用 getSession(true)、Cookie 被攔截、域名/路徑不匹配 | 統一入口獲取 Session;檢查 Cookie 域/路徑;使用 Filter 確保 Session 傳遞 |
| Session 洩漏導致 OOM | 存放大對象、不及時清理、超時配置過長 | 只存必要 ID/引用;定期清理;監控 Session 數量與大小 |
| 集群環境 Session 不同步 | 單機 Session 存儲 | Sticky Session / Session Replication / Spring Session + Redis / Token 無狀態化 |
| 並發請求導致 Session 內容覆蓋 | Servlet 容器對同一 Session 串行化處理,但屬性操作非原子 | 減少 Session 寫入;使用 ConcurrentHashMap 值對象;關鍵操作同步 |
HttpSession,支援 Redis、JDBC、Hazelcast 等分布式存儲,零代碼遷移集群 Session。Session 是 HTTP 無狀態協議上的「狀態補丁」。理解其六重語義、掌握 Cookie/URL 重寫兩大傳輸機制、熟練 HttpSession API、警惕集群與洩漏陷阱,是 Java Web 開發者的必修課。現代架構傾向「無狀態服務 + 分布式 Session / Token」,但 Session 思維仍是基石。