// JSP1
String[] test = {"1", "2"};
request.setAttribute("test", test);
response.sendRedirect("jsp2.jsp"); // 錯誤!取不到值
// JSP2
String[] test = (String[]) request.getAttribute("test"); // null
原因:sendRedirect() 是瀏覽器端重導向,產生兩個獨立請求,第二個 JSP 拿到的是新 request 物件。
// JSP1
request.setAttribute("test", test);
request.getRequestDispatcher("jsp2.jsp").forward(request, response);
// JSP2
String[] test = (String[]) request.getAttribute("test"); // 正常取到
forward() 是伺服器端轉發,**同一個 request 物件**傳遞給目標資源。
| 方式 | 機制 | Request 共享 | 瀏覽器 URL | 適用場景 |
|---|---|---|---|---|
| request.getRequestDispatcher().forward() | 伺服器端轉發 | ✅ 同一個 | 不變 | 同一應用內頁面流轉、攜帶資料 |
| response.sendRedirect() | 瀏覽器端重導向 | ❌ 新請求 | 改變 | 跨應用、防重複提交、權限驗證失敗導向登入 |
| <a href=> / location.href | 超連結/JS跳轉 | ❌ 新請求 | 改變 | 一般導航 |
session.setAttribute()application.setAttribute() 或資料庫// 錯誤:forward 後程式碼繼續執行!
request.getRequestDispatcher("a.jsp").forward(request, response);
request.getRequestDispatcher("b.jsp").forward(request, response); // 拋出 IllegalStateException
// 正確:forward 後立即 return
request.getRequestDispatcher("a.jsp").forward(request, response);
return;
關鍵:forward() **不會終止** 當前方法執行,必須手動 return,否則多次 forward 導致「response already committed」異常。
sendRedirect("login.jsp"):相對**當前 Servlet 路徑**sendRedirect("/login.jsp"):相對**應用根路徑** (Context Path)forward() 不支援相對路徑自動轉換,需用絕對路徑JS 執行於客戶端,JSP 執行於伺服器端,**無法直接互傳**。解決:JSP 寫入 <input type="hidden" value="<%=value%>">,JS 讀取 DOM 取值。