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

Java Web 組件間三大協作模式:轉發、重定向與包含深度解析

     編輯:Java 相關知識

核心差異速查表

特性請求轉發重定向包含
APIRequestDispatcher.forward()HttpServletResponse.sendRedirect()RequestDispatcher.include()
瀏覽器地址欄不變變為目標 URL不變
Request 域共享✅ 同一請求對象❌ 新請求對象✅ 同一請求對象
跨應用/外部資源❌ 僅同一 WebApp✅ 任意 URL❌ 僅同一 WebApp
執行流程伺服器內部跳轉客戶端雙次請求內嵌輸出到響應
典型場景MVC 控制器分派、登入攔截登出、支付回調、防重複提交頁面片段複用(Header/Footer)

1. 請求轉發

Servlet 實現

@WebServlet("/dispatch")
public class DispatchServlet extends HttpServlet {
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) 
            throws ServletException, IOException {
        // 業務邏輯處理...
        req.setAttribute("user", userService.findById(1));
        
        // 轉發到 JSP 渲染
        RequestDispatcher rd = req.getRequestDispatcher("/WEB-INF/views/detail.jsp");
        rd.forward(req, resp);
    }
}

JSP 標籤

<jsp:forward page="/WEB-INF/views/detail.jsp" />

關鍵點

  • 目標資源必須在同一 Web 應用(/ 代表應用上下文根)。
  • 轉發前不可提交響應(如已調用 getWriter() 或 getOutputStream()),否則拋 IllegalStateException。
  • 適用於 Controller → View 模式,隱藏內部結構。

2. 重定向

Servlet 實現

resp.sendRedirect(req.getContextPath() + "/login.jsp"); // 相對路徑自動補全
// 或絕對外部 URL
resp.sendRedirect("https://payment.example.com/callback");

關鍵點

  • 瀏覽器收到 302 狀態碼 + Location 頭,發起第二次請求。
  • 原請求的 request 域屬性全部丟失,需用 session、flash attribute 或 URL 參數傳遞資料。
  • 適用於 POST-Redirect-GET 模式防止表單重複提交、OAuth 回調、跨域跳轉。

3. 包含

Servlet 實現

RequestDispatcher rd = req.getRequestDispatcher("/fragments/header.jsp");
rd.include(req, resp); // 輸出直接寫入當前響應體
rd = req.getRequestDispatcher("/fragments/footer.jsp");
rd.include(req, resp);

JSP 靜態/動態包含

<!-- 靜態包含:編譯期合併,適合不變片段 -->
<%@ include file="/fragments/header.jsp" %>

<!-- 動態包含:運行期處理,可傳參、支援條件判斷 -->
<jsp:include page="/fragments/nav.jsp">
    <jsp:param name="highlight" value="home"/>
</jsp:include>

關鍵點

  • 被包含頁面不應有 <html><body> 等根標籤,避免產生非法 HTML 結構。
  • 包含頁面共享 request/response,可讀取屬性、寫入輸出流。
  • 動態包含 (jsp:include) 允許傳參,靜態包含 (@ include) 效能略高但無法傳參。

進階:Spring MVC 中的視圖解析

@Controller
public class UserController {
    @GetMapping("/user/{id}")
    public String detail(@PathVariable Long id, Model model) {
        model.addAttribute("user", userService.get(id));
        return "user/detail"; // 邏輯視圖名,由 ViewResolver 解析為 /WEB-INF/views/user/detail.jsp
    }
    
    @PostMapping("/user")
    public RedirectView create(UserForm form) {
        User u = userService.save(form);
        return new RedirectView("/user/" + u.getId(), true); // PRG 模式
    }
}

總結選型建議

  1. 需隱藏內部路徑、共享請求數據 → 轉發
  2. 需改變瀏覽器 URL、防重複提交、跨應用跳轉 → 重定向
  3. 需組合頁面片段、複用 Header/Footer/側邊欄 → 包含
  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved