在 Web 開發中,Session 是維持用戶會話狀態的關鍵機制。本文將從 Servlet 原理出發,深入分析 Struts 框架中 Session 的創建時機、SessionId 生成與傳遞流程,並揭示 Struts 內部機制導致的 Session 提前創建現象。
Session 對象在客戶端首次請求時創建,伺服器生成唯一的 SessionId,並透過響應頭(Set-Cookie)或 URL 重寫方式返回給瀏覽器。後續請求中,瀏覽器攜帶 SessionId,伺服器據此檢索對應 Session。若 Session 尚未失效且伺服器未重啟,則直接返回現有 Session;否則創建新 Session 並生成新 SessionId。
實際測試發現:在 Struts + JSP 環境下,即使業務代碼(Action、JSP)未顯式調用 request.getSession(),首次請求 *.do 時,request.getCookies() 竟能取得 JSESSIONID。追蹤源碼發現,罪魁禍首是 RequestProcessor 的 processLocale() 方法:
protected void processLocale(HttpServletRequest request, HttpServletResponse response) {
if (!moduleConfig.getControllerConfig().getLocale()) return;
HttpSession session = request.getSession(); // 這裡創建了 Session!
if (session.getAttribute(Globals.LOCALE_KEY) != null) return;
Locale locale = request.getLocale();
if (locale != null) session.setAttribute(Globals.LOCALE_KEY, locale);
}
struts-config.xml 中 <controller locale="true"> 預設為開啟,導致 ActionServlet 將請求委派給 RequestProcessor 時,在進入用戶 Action 之前就已創建 Session 並生成 Cookie。
struts-config.xml 設定 <controller locale="false">,可阻止框架層面的預先創建。request.getSession(true)。isNew() 返回 true,因尚未響應給客戶端;業務代碼中獲取的同一 Session 同樣為 true,需注意邏輯判斷。理解這一機制,有助於避免不必要的 Session 開銷,精準控制會話生命週期,提升應用效能與安全性。