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

JSP Filter 重定向死循環:Response 提交與 Filter 鏈執行順序誤解

     編輯:程式設計綜合問答

現象

Filter 中 `response.sendRedirect("second.jsp")`,但 Console 仍輸出 `doFilter----first---end`,看似「重定向後仍繼續執行」。

根本原因

重定向是客戶端行為:`sendRedirect` 只是在 HTTP 回應中設定 `Location` 標頭與 302 狀態碼,**伺服器端程式碼繼續執行完畢**,才將回應送回瀏覽器。瀏覽器收到 302 **再** 發起新請求到 `second.jsp`,觸發第二次 Filter 鏈。

執行流程圖解


請求 first.jsp
   │
   ▼
Filter.doFilter (first)
   │  ├─ chain.doFilter(req, resp) → Servlet/JSP 執行
   │  ├─ resp.sendRedirect("second.jsp")  // 只是設定 Header
   │  ├─ System.out.println("doFilter----first---end")  // 繼續執行!
   │  └─ 方法返回,Container 發送 302 回應
   ▼
瀏覽器收到 302 Location: second.jsp
   │
   ▼
請求 second.jsp  (新請求!)
   │
   ▼
Filter.doFilter (second)  // 再次進入 Filter
   │  ...

正確阻斷後續執行


public void doFilter(ServletRequest req, ServletResponse resp, FilterChain chain) {
    HttpServletRequest request = (HttpServletRequest) req;
    HttpServletResponse response = (HttpServletResponse) resp;

    if (shouldRedirect(request)) {
        response.sendRedirect("second.jsp");
        return; // 【關鍵】直接 return,不再呼叫 chain.doFilter,也不執行後續程式碼
    }

    chain.doFilter(request, response); // 正常通過
    // 後續 log 等...
}

關鍵原則

  • `sendRedirect` / `forward` 後,**必須 `return`** 結束當前 `doFilter`/`service` 方法。
  • Filter 鏈 `chain.doFilter` 只有在**決定放行**時呼叫。
  • 重定向產生**新請求**,會完整走一次 Filter → Servlet 流程,非同一執行緒「跳轉」。
  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved