| 特性 | response.sendRedirect() | RequestDispatcher.forward() |
|---|---|---|
| 執行位置 | 客戶端(瀏覽器) | 服務端(容器內部) |
| 請求對象 | 新請求(原 request 失效) | 同一請求(保留屬性、參數) |
| 地址欄 URL | 變為目標 URL | 保持原 URL 不變 |
| 跨域/跨容器 | 支持 | 僅限同一 Web 應用 |
| 目標資源 | 任意 URL(HTML、JSP、Servlet、外部站點) | 同應用內資源(JSP、Servlet、HTML) |
| Frame 頁面 | 支持 | 不支持含 Frame 的 JSP(HTML 可) |
| 攜帶參數 | URL 後拼接 ?k=v | 需用 request.setAttribute() |
| 執行流程 | 發送 302 + Location,瀏覽器再發新請求 | 容器內直接調用目標資源的 service() |
sendRedirect 關鍵細節若緩衝區已 flush(默認 8KB),拋出 IllegalStateException。解決:調大緩衝區 <%@ page buffer="32kb" %>,或確保重定向前無輸出。
returnresponse.sendRedirect("target.jsp");
return; // 防止後續代碼繼續執行導致異常或邏輯錯誤
response.encodeRedirectURL(request.getContextPath() + "/target.jsp") 自動攜帶 SessionID。/ 開頭,相對 Context Root。forward 關鍵細節跨應用需用 getServletContext().getContext("/otherApp").getRequestDispatcher(...)(容器需啟用 crossContext)。
request.setAttribute("user", userObj);
request.getRequestDispatcher("/detail.jsp").forward(request, response);
轉發後目標資源再次 forward 可能導致無限循環,設計清晰的控制器層。
forward 到結果頁(保留數據、刷新不重複提交)。sendRedirect 到登入頁(URL 可見、可收藏、清空請求數據)。Result 類型(dispatcher/redirect),開發者無需直接調用底層 API。encodeRedirectURL,且瀏覽器禁用 Cookie → URL 重寫失效。server.xml 設置 URIEncoding="UTF-8" 或使用 Filter 統一編碼。「轉發是服務端的內部協作,重定向是客戶端的跳轉指令。」根據業務語義選擇:需保留請求上下文用 forward,需改變 URL、跨應用、結束事務用 redirect。