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

request.getRequestDispatcher() vs response.sendRedirect():轉發與重定向核心差異、適用場景與坑點全解析

     編輯:Java 綜合教學

轉發 vs 重定向:核心差異全解析

`RequestDispatcher.forward()` (伺服器端轉發) 與 `HttpServletResponse.sendRedirect()` (客戶端重定向) 是 Servlet 開發最易混淆的兩大跳轉方式。本文從請求對象共享、地址欄變化、執行位置、跨應用能力、參數傳遞、緩衝區限制**六大維度深度對比。

核心差異對比表

維度forward (轉發)sendRedirect (重定向)
執行位置伺服器內部 (容器)客戶端瀏覽器
請求對象同一個 request 共享屬性新建 request,舊屬性丟失
瀏覽器地址欄不變 (仍為原 URL)改變 為目標 URL
HTTP 狀態碼200 (單次請求)302 (兩次請求:302 → 新請求)
跨 Web 應用需 `ServletContext.getContext(uri).getRequestDispatcher()`支援任意 URL (含外部域名)
參數傳遞只能 `request.setAttribute()`URL 參數 `?id=1` 或 Session
目標資源類型同應用內 Servlet/JSP/HTML任意資源 (HTML、JSP、Servlet、外部站點)
Frame/Iframe 相容不支援含 frame 的 JSP (部分容器)完全支援
緩衝區限制響應未提交前可調用 (`isCommitted()`)隨時可調用 (發送 302 即提交)
刷新行為重複提交風險 (重新執行轉發邏輯)重複最後一個 GET 請求 (相對安全)

代碼對比

// ========== forward ==========
// Servlet A
request.setAttribute("user", userObj);
request.getRequestDispatcher("/result.jsp").forward(request, response);
// result.jsp 可直接 ${user} 取值,地址欄仍為 /servletA

// ========== sendRedirect ==========
// Servlet B
response.sendRedirect("/result.jsp?userId=" + user.getId());
// result.jsp 需 request.getParameter("userId") 重新查詢,地址欄變為 /result.jsp

路徑解析規則:相對/絕對路徑陷阱

場景forward 路徑sendRedirect 路徑
應用上下文 `/myapp`相對當前請求路徑
`rd.forward("/b")` → `/myapp/b`
`getServletContext().getRD("/b")` → `/myapp/b`
相對伺服器根
`resp.sendRedirect("/b")` → `https://host/b`
`resp.sendRedirect("b")` → `https://host/myapp/current/path/b`
跨應用`ctx = getServletContext().getContext("/otherApp"); ctx.getRD("/b").forward(req,resp);``resp.sendRedirect("https://host/otherApp/b");`

進階用法與最佳實踐

  1. PRG 模式 (Post-Redirect-Get):表單 POST 處理完 `sendRedirect` 到結果頁,防止 F5 重複提交。
  2. 轉發傳遞複雜對象:`request.setAttribute("key", obj)` + `forward`,目標頁面 `${key.property}` 直接取值。
  3. 重定向傳遞閃存數據:`RedirectAttributes.addFlashAttribute("msg", "成功")` (Spring MVC) → 目標請求可取一次。
  4. 避免 forward 死循環:A forward B,B forward A → StackOverflowError。
  5. 緩衝區檢查:`if (!response.isCommitted()) forward(); else redirect();`

JSP 標籤對應

<jsp:forward page="/result.jsp" />           <!-- 等同 request.getRD().forward() -->
<c:redirect url="/result.jsp" />            <!-- JSTL 封裝 sendRedirect -->
<meta http-equiv="refresh" content="0;url=/result.jsp" /> <!-- HTML Meta 刷新 -->

選型決策樹

  1. 需共享 request 屬性?→ forward
  2. 2. 需改變瀏覽器 URL (書籤、分享、SEO)?→ sendRedirect 3. 跨域/外部站點?→ sendRedirect 4. 表單提交後防重複?→ sendRedirect (PRG) 5. 目標含 frameset?→ sendRedirect 6. 以上皆否,單純內部跳轉?→ forward (效能略高,單次請求)

精準掌握轉發與重定向語義邊界,是 Servlet/JSP/Web 框架開發者的必修基本功。

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