在 Servlet 開發中,常見的一個困擾是:在一個 Servlet 中寫入 Cookie 後,緊接著使用 forward 轉發到另一個 Servlet 讀取,卻發現讀不到剛寫入的 Cookie,只能讀到上一次請求攜帶的舊 Cookie。這究竟是為什麼?我們該如何解決?
要理解這個問題,必須搞清楚 HTTP 請求處理的流程:
response.addCookie() 寫入新 Cookie,這實際上是將 Set-Cookie 標頭加入 HTTP 響應中,數據已經發送給客戶端。request.getCookies(),依然是步驟 1 中客戶端攜帶的舊 Cookie。簡單說:寫入 Cookie 影響的是「下一次請求」,而轉發發生在「同一次請求」內部。
在寫入 Cookie 後,同步將數據存入 request.setAttribute() 或 session.setAttribute()。後續轉發的 Servlet 優先從 Request/Session 讀取,兜底再讀 Cookie。這樣能立即獲取最新數據,且不依賴客戶端下一次請求。
將 forward 改為 response.sendRedirect()。重定向會讓伺服器返回 302 狀態碼和新位置給瀏覽器,瀏覽器隨即發起全新的 HTTP 請求。這時新 Cookie 已在瀏覽器端,新請求自然會攜帶它,第二個 Servlet 就能正常讀取了。
// 錯誤示範:forward 無法讀取新 Cookie
request.getRequestDispatcher("/readCookie").forward(request, response);
// 正確做法:redirect 觸發新請求,可讀取新 Cookie
response.sendRedirect(request.getContextPath() + "/readCookie");
方案二更簡潔、符合 HTTP 語義,也是解決此類問題的標準做法。
Cookie 的生效需要經過「響應 → 客戶端存儲 → 下一次請求」的完整週期。轉發不會產生新請求,自然讀不到新 Cookie。掌握這一機制,靈活選擇 Redirect 或本地暫存,即可輕鬆解決 Servlet Cookie 讀取時序問題。