HTTP 協議本質上是一個無狀態協議,這意味著伺服器無法自行判斷多個請求是否來自同一個瀏覽器,也就無法與瀏覽器建立持續的會話關係。為了解決這一問題,Web 開發引入了會話控制技術,主要包括客戶端的 Cookie 技術和伺服器端的 Session 技術。
Cookie 是儲存在瀏覽器端的緩存技術。當瀏覽器首次向伺服器發送請求時,伺服器會創建 Cookie 物件,以鍵值對形式放在響應頭中返回。瀏覽器後續發送請求時,會自動在請求頭中攜帶這些 Cookie 資訊,讓伺服器識別客戶端身份。
new Cookie(key, value) 創建,再透過 response.addCookie(cookie) 送回瀏覽器。request.getCookies() 取得 Cookie 陣列,若無 Cookie 則回傳 null。setMaxAge(seconds):
seconds 為負數,儲存在瀏覽器記憶體中,關閉瀏覽器即失效。seconds 為正數,儲存在本地檔案系統,保存指定秒數。setMaxAge(0) 即可立即刪除。Session 是伺服器端的緩存技術,但它依賴 Cookie 運作。核心流程如下:
getSession() 創建 Session 物件,並建立名為 JSESSIONID 的 Cookie 返回給瀏覽器。JSESSIONID 查找現有 Session:
// 獲取 Session 並設定持久化 Cookie
HttpSession session = request.getSession();
String id = session.getId();
Cookie cookie = new Cookie("JSESSIONID", id);
cookie.setMaxAge(30);
response.addCookie(cookie);
// 設定 Session 空閒失效時間(秒)
session.setMaxInactiveInterval(10);
// 強制 Session 失效
session.invalidate();
若瀏覽器禁用 Cookie,可使用 URL 重寫將 JSESSIONID 附加在 URL 後:
HttpSession session = request.getSession();
session.setAttribute("attrName", "testValue");
String url = "target url";
url = response.encodeURL(url);
response.sendRedirect(url);
注意:目標頁面若需維持 Session,同樣必須實作 URL 重寫。
request.getSession() 行為:若為客戶端存取的第一個 Web 資源則創建 Session;但若 JSP 頁面指定 session="false",則不會創建。session="false" 的含義:僅禁用當前頁面的 session 隱含變數,仍可使用顯式的 HttpSession 物件。簡單來說,Cookie 是伺服器與瀏覽器溝通的識別碼。HTTP 無狀態,會話靠 Cookie 維繫(JSESSIONID),Session 建立在 Cookie 之上。理解這層關係,是掌握 Web 會話控制的關鍵。