首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> 網頁程式設計 >> JSP 程式設計 >> 關於JSP

JSP/Servlet 重定向與轉發深度解析

     編輯:關於JSP

核心區別一覽

特性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 關鍵細節

1. 不能有已提交的響應內容

若緩衝區已 flush(默認 8KB),拋出 IllegalStateException。解決:調大緩衝區 <%@ page buffer="32kb" %>,或確保重定向前無輸出。

2. 必須配合 return

response.sendRedirect("target.jsp");
return; // 防止後續代碼繼續執行導致異常或邏輯錯誤

3. 相對/絕對路徑處理

  • 相對路徑:相對當前請求 URL,建議用 response.encodeRedirectURL(request.getContextPath() + "/target.jsp") 自動攜帶 SessionID。
  • 絕對路徑:以 / 開頭,相對 Context Root。

轉發 forward 關鍵細節

1. 僅限同一 ServletContext

跨應用需用 getServletContext().getContext("/otherApp").getRequestDispatcher(...)(容器需啟用 crossContext)。

2. 請求屬性傳遞

request.setAttribute("user", userObj);
request.getRequestDispatcher("/detail.jsp").forward(request, response);

3. 避免重複 forward

轉發後目標資源再次 forward 可能導致無限循環,設計清晰的控制器層。

最佳實踐

  • 流程控制:表單提交 → Servlet 處理業務 → forward 到結果頁(保留數據、刷新不重複提交)。
  • 權限檢查失敗:sendRedirect 到登入頁(URL 可見、可收藏、清空請求數據)。
  • PRG 模式:Post-Redirect-Get,防止表單重複提交。
  • 框架整合:Struts2/SpringMVC 封裝了 Result 類型(dispatcher/redirect),開發者無需直接調用底層 API。

常見錯誤排查

  1. 重定向後 Session 丟失:未使用 encodeRedirectURL,且瀏覽器禁用 Cookie → URL 重寫失效。
  2. forward 後請求參數亂碼:Tomcat 8+ 需在 server.xml 設置 URIEncoding="UTF-8" 或使用 Filter 統一編碼。
  3. 重定向循環:登入攔截器邏輯缺陷,未排除登入頁自身。

總結

「轉發是服務端的內部協作,重定向是客戶端的跳轉指令。」根據業務語義選擇:需保留請求上下文用 forward,需改變 URL、跨應用、結束事務用 redirect。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved