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

深入理解 Java Servlet 過濾器:原理、生命週期與實戰應用

     編輯:Java 綜合教學

什麼是過濾器?

過濾器是一個可插入 Web 應用程式的組件,用於攔截客戶端請求與伺服器響應,並對其進行預處理或後處理。透過過濾器,開發者可以在請求到達目標資源(如 Servlet、JSP)之前,或響應返回給客戶端之前,執行邏輯判斷、資料轉換、編碼設定、權限驗證等操作,最終保留有效的資料流。

過濾器的生命週期

Web 容器負責管理過濾器的完整生命週期,主要包含三個階段:

1. 實例化

容器啟動時,透過無參建構子建立過濾器實例,整個應用生命週期中只會實例化一次。

2. 初始化

實例化完成後,容器呼叫 init(FilterConfig config) 方法,傳入配置參數。此方法同樣只會被呼叫一次,適合載入靜態資源或初始化連線池。

3. 執行過濾

每當有符合攔截路徑的請求進入,容器便呼叫 doFilter(ServletRequest, ServletResponse, FilterChain) 方法。開發者在該方法中編寫核心邏輯,並透過 chain.doFilter() 將請求傳遞給鏈中的下一個過濾器或目標資源。

4. 銷毀

應用關閉或過濾器被移除時,容器呼叫 destroy() 釋放資源(如關閉資料庫連線、釋放記憶體)。

開發過濾器的四大步驟

  1. 建立實作 javax.servlet.Filter 介面的類別。
  2. 在 doFilter() 中實作具體的過濾邏輯。
  3. 呼叫 chain.doFilter(request, response) 將請求傳遞給下一環節。
  4. 在 web.xml 中宣告 <filter> 與 <filter-mapping> 進行註冊與映射。

程式碼範例:字元編碼過濾器

package demo.web.filter;

import java.io.IOException;
import javax.servlet.*;

public class CharacterEncodingFilter implements Filter {
    @Override
    public void init(FilterConfig filterConfig) throws ServletException {
        // 初始化邏輯,如讀取編碼參數
    }

    @Override
    public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain)
            throws IOException, ServletException {
        // 統一設定請求與響應編碼
        request.setCharacterEncoding("UTF-8");
        response.setCharacterEncoding("UTF-8");
        chain.doFilter(request, response);
    }

    @Override
    public void destroy() {
        // 釋放資源
    }
}

另一個範例:日誌過濾器

package demo.web.filter;

import java.io.IOException;
import javax.servlet.*;

public class MyFilter implements Filter {
    @Override
    public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain)
            throws IOException, ServletException {
        System.out.println("MyFilter: doFilter 開始");
        request.setCharacterEncoding("UTF-8");
        chain.doFilter(request, response);
        response.setCharacterEncoding("UTF-8");
        System.out.println("MyFilter: doFilter 結束");
    }
    // init / destroy 略
}

web.xml 設定詳解

<filter>
    <filter-name>CharacterEncodingFilter</filter-name>
    <filter-class>demo.web.filter.CharacterEncodingFilter</filter-class>
</filter>
<filter-mapping>
    <filter-name>CharacterEncodingFilter</filter-name>
    <url-pattern>/*</url-pattern>
</filter-mapping>

<filter>
    <filter-name>myFilter</filter-name>
    <filter-class>demo.web.filter.MyFilter</filter-class>
</filter>
<filter-mapping>
    <filter-name>myFilter</filter-name>
    <url-pattern>/*</url-pattern>
    <dispatcher>REQUEST</dispatcher>
</filter-mapping>

dispatcher 子元素說明

<dispatcher> 指定過濾器攔截的請求調用方式,可設定多個,預設為 REQUEST:

  • REQUEST:直接訪問頁面時觸發;透過 RequestDispatcher.include() 或 forward() 訪問時不觸發。
  • INCLUDE:僅當目標資源透過 include() 調用時觸發。
  • FORWARD:僅當目標資源透過 forward() 調用時觸發。
  • ERROR:僅當目標資源透過聲明式異常處理機制調用時觸發。

過濾器鏈

Web 應用可配置多個過濾器,它們按照在 web.xml 中的註冊順序形成一條鏈。容器建立 FilterChain 物件傳給第一個過濾器的 doFilter,開發者呼叫 chain.doFilter() 後,容器會檢查鏈中是否還有下一個過濾器,若有則繼續執行,否則調用目標 Servlet。

執行順序示意:

  1. Servlet 初始化
  2. Filter1 doFilter 前半段
  3. Filter2 doFilter 前半段
  4. 目標 Servlet service() / doGet()
  5. Filter2 doFilter 後半段
  6. Filter1 doFilter 後半段

過濾器鏈執行流程圖

控制台輸出結果

注意: Servlet 僅初始化一次;過濾器類別位於 javax.servlet 套件下。

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