Session 一詞的多重語義
「Session」是計算機科學中最容易混淆的術語之一,根據上下文至少有六種含義:
- 瀏覽器會話期:從瀏覽器窗口打開到關閉的期間。
- 用戶業務會話:為完成特定目標的一系列動作(如登錄→選購→結賬→登出)。
- 網絡協議會話:面向連接、保持狀態的通信過程(如 TCP Session、POP3 Session)。
- Web Session 機制:在無狀態 HTTP 之上維持客戶端狀態的解決方案(Cookie、URL 重寫、隱藏表單)。
- Session 存儲結構:服務端保存會話數據的容器(如「把用戶對象放入 Session」)。
- 語言特定 API:如 Java 的
javax.servlet.http.HttpSession。
本文聚焦於第 4、5、6 種含義:Web 應用中的 Session 機制及其 Java 實現。
HTTP 無狀態與 Session 產生背景
HTTP 協議本質無狀態,每次請求獨立。為了識別同一用戶的多次請求,需引入會話追蹤機制:
- Cookie:服務端發送
Set-Cookie: JSESSIONID=xxx,客戶端自動攜帶。
- URL 重寫:
/app/page.jsp;jsessionid=xxx,適用於禁用 Cookie 環境。
- 隱藏表單:表單中攜帶
<input type="hidden" name="jsessionid" value="xxx">。
Servlet 容器封裝上述細節,提供 HttpSession 統一 API。
HttpSession 核心 API 與生命週期
| 方法 | 說明 |
getId() | 獲取唯一會話 ID |
getAttribute(name) / setAttribute(name, value) | 讀寫會話屬性(替代舊版 getValue/putValue) |
removeAttribute(name) | 移除屬性 |
invalidate() | 銷毀 Session,解綁所有屬性 |
getMaxInactiveInterval() / setMaxInactiveInterval(seconds) | 獲取/設置超時時間(預設 30 分鐘,web.xml 配置) |
isNew() | 判斷是否為新創建的 Session(客戶端未攜帶有效 ID) |
getCreationTime() / getLastAccessedTime() | 創建時間 / 最後訪問時間(毫秒時間戳) |
Session 範圍與屬性共享
在 JSP 中,session 隱含對象即 HttpSession 實例。屬性存儲於服務端內存(或持久化/分布式存儲),同一瀏覽器會話期內的所有請求共享同一 Session 實例。
<%-- 存入 --%> session.setAttribute("user", userObj);
<%-- 取出 --%> User u = (User) session.getAttribute("user");
常見誤區與最佳實踐
- 誤以為關閉瀏覽器即銷毀 Session:Session 存儲在服務端,僅當超時或調用
invalidate() 時銷毀。關閉瀏覽器僅丟失 Cookie,下次打開若 Session 未超時,攜帶舊 JSESSIONID 仍可恢復會話。
- 濫用 Session 存放大對象:導致內存溢出、序列化失敗(集群環境)。原則:僅存放必要的業務標識(用戶 ID、權限標籤),大數據查詢結果用緩存(Redis/Ehcache)。
- 忽略並發訪問同步:多標籤頁並發請求可能並發修改 Session 屬性,需同步或使用線程安全集合。
- 未配置會話超時:
web.xml 設置 <session-config><session-timeout>15</session-timeout></session-config>(單位:分鐘)。
- 集群環境 Session 複製/黏性會話:配置負載均衡器 Sticky Session 或啟用 Session 複製(
replication-mode),否則用戶請求分發到不同節點導致會話丟失。
Session 安全加固
- 全站 HTTPS,Cookie 設置
Secure、HttpOnly、SameSite=Strict/Lax。
- 登入後重新生成 Session ID(
session.invalidate() → request.getSession(true)),防止 Session Fixation 攻擊。
- 敏感操作二次驗證(密碼、短信碼),不僅依賴 Session。
- 定期審計活躍 Session 數量,異常激增可能為攻擊或洩漏。
總結
Session 是 Web 有狀態交互的基石。理解其多重含義、底層機制、API 細節與安全陷阱,能幫助開發者構建健壯、安全、可擴展的會話管理體系。
- 上一篇文章: AJAX + JSP 實現無刷新驗證碼校驗,優化用戶體驗
- 下一篇文章: JSF 與 JSP 整合開發:構建組件化 Web 表現層
Copyright ©
程式碼之家 All Rights Reserved