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

Java Servlet 與 JSP 頁面跳轉方式完整比較:forward vs redirect

     編輯:Java 程式設計入門

核心差異速查表

特性forward (請求轉發)redirect (重導向)
機制伺服器端內部轉發瀏覽器端發起新請求
URL 變化不變變為目標 URL
請求物件共享同一 request新 request,原 request 失效
資料傳遞request.setAttribute / session / 參數session / URL 參數
目標範圍同一 Web 應用內部任意 URL (含外部網站)
速度較快 (一次請求)較慢 (兩次請求)
刷新行為重複提交原表單重新請求目標頁面

Servlet 實作方式

1. forward - RequestDispatcher


// 方式一:透過 request
RequestDispatcher rd = request.getRequestDispatcher("/result.jsp");
rd.forward(request, response);

// 方式二:透過 ServletContext (跨應用需 crossContext=true)
getServletContext().getRequestDispatcher("/otherApp/page.jsp").forward(request, response);

2. redirect - sendRedirect


// 相對路徑 (相對當前應用 context path)
response.sendRedirect("success.jsp");

// 絕對路徑 (相對網域根目錄)
response.sendRedirect("/myapp/dashboard.jsp");

// 外部網站
response.sendRedirect("https://www.example.com");

JSP 實作方式

1. <jsp:forward> 標籤


<jsp:forward page="/result.jsp">
    <jsp:param name="msg" value="操作成功" />
</jsp:forward>

2. response.sendRedirect() 在 JSP 中的陷阱


<% 
    // 錯誤:out.flush() 後不能 redirect
    out.println("處理中...");
    out.flush(); // 已提交回應
    response.sendRedirect("ok.jsp"); // 拋出 IllegalStateException
%>

解決:邏輯判斷前置,或使用 <c:redirect> (JSTL),或改用 forward。

3. response.setHeader("Location", url)


<%
    response.setHeader("Location", "login.jsp");
    response.setStatus(HttpServletResponse.SC_MOVED_TEMPORARILY); // 302
%>

等同於 sendRedirect,但需手動設定狀態碼,不建議直接使用。

資料傳遞最佳實踐

forward 時傳遞複雜物件


// Servlet
User user = userService.findById(id);
request.setAttribute("user", user);
request.getRequestDispatcher("/user/detail.jsp").forward(request, response);

// JSP (EL 表達式)
${user.username} - ${user.email}

redirect 時傳遞資料 (PRG 模式)


// POST 處理完成後 redirect 到 GET 頁面,避免重複提交
@WebServlet("/user/save")
public class UserSaveServlet extends HttpServlet {
    protected void doPost(HttpServletRequest req, HttpServletResponse resp) {
        User user = parseUser(req);
        userService.save(user);
        
        // 方式一:session 暫存 (適合成功訊息)
        req.getSession().setAttribute("flashMsg", "儲存成功");
        
        // 方式二:URL 參數 (適合 ID 導向)
        resp.sendRedirect(req.getContextPath() + "/user/detail?id=" + user.getId());
    }
}

常見問題與解決方案

問題原因解決
IllegalStateException: Cannot forward after response has been committed已有輸出內容 (out.flush/println) 後嘗試 forward調整邏輯順序,前置判斷;或增加緩衝區大小 response.setBufferSize()
forward 後表單重複提交瀏覽器重新整理重送 POST採用 PRG 模式:POST 處理完 redirect 到 GET 頁面
redirect 丟失 request 屬性redirect 產生新 request改用 session、URL 參數、或 Spring FlashMap
跨應用 forward 失效預設禁止跨應用轉發Tomcat context.xml 設定 crossContext="true"

架構選擇指南

選擇 forward 當:

  • 同一業務流程內的頁面跳轉 (Controller → View)
  • 需保留 request 參數/屬性給目標頁面
  • 表單驗證失敗返回原頁面顯示錯誤
  • 避免瀏覽器地址列暴露內部結構

選擇 redirect 當:

  • POST 請求處理完成 (PRG 模式防重複提交)
  • 跳轉到外部系統/不同域名
  • 登入成功導向首頁、登出導向登入頁
  • 需讓用戶可書籤/分享目標 URL
  • 權限不足導向錯誤頁 (403/404)

總結

forward 是伺服器端內部協作,redirect 是瀏覽器端雙向互動。現代 Web 開發核心原則:POST 請求必須 redirect (PRG 模式),GET 請求視情境選擇。善用 request.setAttribute 配合 forward 傳遞模型資料,用 session/URL 參數配合 redirect 傳遞狀態資訊,構建清晰、安全、用戶體驗良好的 Web 應用。

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