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

Servlet/JSP 服務端重定向深度解析:forward vs sendRedirect 核心差異與最佳實踐

     編輯:關於JSP

服務端重定向是 MVC 架構中 Controller 轉向 View、多步驟業務流轉的核心機制。本文系統對比 RequestDispatcher.forward() 與 HttpServletResponse.sendRedirect(),剖析底層原理、適用場景與常見坑點。

兩大方式對比總覽

維度forward (RequestDispatcher)sendRedirect (HttpServletResponse)
發起方伺服器內部瀏覽器(客戶端)
請求次數1 次2 次(302 + 新請求)
URL 變化瀏覽器地址欄不變地址欄變為新 URL
請求對象共享同一 request/response新請求,原 request 屬性丟失
目標範圍同一 Web 應用(或跨上下文 getContext())任意 URL(跨域、跨應用、外部站點)
速度快(無網路往返)稍慢(額外一次請求)
刷新行為刷新重執行原請求刷新重執行目標頁
適用場景Controller→View、多步驟表單、權限攔截轉登入登入成功跳首頁、POST-Redirect-GET 模式、跨應用跳轉

RequestDispatcher 獲取三大途徑

// 1. 相對當前請求路徑(可不以 / 開頭)
RequestDispatcher rd1 = request.getRequestDispatcher("sub/page.jsp");

// 2. 相對 Web 應用根目錄(必須以 / 開頭)
RequestDispatcher rd2 = getServletContext().getRequestDispatcher("/app/page.jsp");

// 3. 依名稱獲取(需在 web.xml 定義 )
RequestDispatcher rd3 = getServletContext().getNamedDispatcher("myServlet");

forward 關鍵限制與異常處理

  • 緩衝區已提交:若 response 已 flush() 或緩衝區滿自動提交,呼叫 forward() 拋 IllegalStateException。解決:<%@ page buffer="16kb" autoFlush="false" %> 或確保前無輸出。
  • forward() 前自動 clearBuffer(),但不清除已提交的 Header。
  • 目標資源可再次 forward,形成鏈,但需防循環。

sendRedirect 相對路徑解析規則

  • response.sendRedirect("page.jsp"):相對當前請求 URL 目錄。
  • response.sendRedirect("/app/page.jsp"):相對Web 應用根目錄(Context Path)。
  • response.sendRedirect("https://other.com"):絕對 URL,跨域跳轉。

最佳實踐:POST-Redirect-GET (PRG) 模式

@PostMapping("/order")
public String createOrder(OrderForm form, RedirectAttributes ra) {
  Order order = orderService.create(form);
  ra.addFlashAttribute("msg", "訂單創建成功,編號:" + order.getId());
  return "redirect:/order/detail/" + order.getId(); // 302 到 GET 頁面
}
  • 避免表單重複提交(F5 重新整理不再 POST)。
  • Flash 屬性經 Session 傳遞一次性訊息。

跨上下文 Forward 進階

ServletContext otherCtx = getServletContext().getContext("/anotherApp");
if (otherCtx != null) {
  RequestDispatcher rd = otherCtx.getRequestDispatcher("/target.jsp");
  rd.forward(request, response); // 需目標應用 true
}

需在目標應用 context.xml 設定 <Context crossContext="true">,且安全性需謹慎評估。

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