| 維度 | <jsp:forward> (伺服器端轉發) | response.sendRedirect() (客戶端重導向) |
|---|---|---|
| 瀏覽器地址列 | **不變** (仍顯示原 URL) | **改變** (顯示新 URL) |
| 請求對象 | **同一個 request** 傳遞給目標資源 | **新 request**,原 request 屬性丟失 |
| 作用域 | 僅限同一 Web 應用內部資源 | 可重導向到任意絕對/相對 URL (含外部站點) |
| 效能 | 單次網路往返,略快 | 雙次往返 (302 + 新請求),略慢 |
| 刷新行為 | 重新執行原請求邏輯 (可能重複提交) | 重新執行目標 URL (安全,符合 PRG 模式) |
| 代碼執行順序 | forward 後的代碼**不執行** (控制權移交) | sendRedirect 後的代碼**繼續執行** (僅設置響應頭) |
turnAfter.html<html><body><h1>編程入門網:https://www.bianceng.cn</h1></body></html>
<jsp:forward> — turn_01.jsp<%@ page contentType="text/html;charset=gbk" %>
<html><body>
<% System.out.println("====forward跳轉之前========="); %>
<jsp:forward page="turnAfter.html"/>
<% System.out.println("====forward跳轉之後========="); %> <!-- 不會輸出 -->
</body></html>
**控制台輸出**:====forward跳轉之前=========
(無「之後」)
response.sendRedirect() — turn_02.jsp<%@ page contentType="text/html;charset=gbk" %>
<html><body>
<% System.out.println("====response跳轉之前========="); %>
<% response.sendRedirect("turnAfter.html"); %>
<% System.out.println("====response跳轉之後========="); %> <!-- 會輸出 -->
</body></html>
**控制台輸出**:====response跳轉之前=============response跳轉之後=========
request 屬性 → <jsp:forward>sendRedirect()sendRedirect()<jsp:forward>sendRedirect("/login") (配合 return 結束後續代碼)return "forward:/view" vs return "redirect:/view"<result type="chain"> (Action 鏈,類似 forward) vs <result type="redirect">request.getRequestDispatcher("/view").forward(req, resp) vs resp.sendRedirect("/view")@WebServlet("/submit")
public class SubmitServlet extends HttpServlet {
protected void doPost(HttpServletRequest req, HttpServletResponse resp) {
// 1. 處理業務邏輯
// 2. 重導向到結果頁,防止 F5 重複提交
resp.sendRedirect(req.getContextPath() + "/result?status=success");
}
}
**永遠在 POST 處理完成後使用 sendRedirect**,除非你明確需要 forward 的 request 共享特性。