過濾器是一個可插入 Web 應用程式的組件,用於攔截客戶端請求與伺服器響應,並對其進行預處理或後處理。透過過濾器,開發者可以在請求到達目標資源(如 Servlet、JSP)之前,或響應返回給客戶端之前,執行邏輯判斷、資料轉換、編碼設定、權限驗證等操作,最終保留有效的資料流。
Web 容器負責管理過濾器的完整生命週期,主要包含三個階段:
容器啟動時,透過無參建構子建立過濾器實例,整個應用生命週期中只會實例化一次。
實例化完成後,容器呼叫 init(FilterConfig config) 方法,傳入配置參數。此方法同樣只會被呼叫一次,適合載入靜態資源或初始化連線池。
每當有符合攔截路徑的請求進入,容器便呼叫 doFilter(ServletRequest, ServletResponse, FilterChain) 方法。開發者在該方法中編寫核心邏輯,並透過 chain.doFilter() 將請求傳遞給鏈中的下一個過濾器或目標資源。
應用關閉或過濾器被移除時,容器呼叫 destroy() 釋放資源(如關閉資料庫連線、釋放記憶體)。
javax.servlet.Filter 介面的類別。doFilter() 中實作具體的過濾邏輯。chain.doFilter(request, response) 將請求傳遞給下一環節。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 略
}
<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> 指定過濾器攔截的請求調用方式,可設定多個,預設為 REQUEST:
RequestDispatcher.include() 或 forward() 訪問時不觸發。include() 調用時觸發。forward() 調用時觸發。Web 應用可配置多個過濾器,它們按照在 web.xml 中的註冊順序形成一條鏈。容器建立 FilterChain 物件傳給第一個過濾器的 doFilter,開發者呼叫 chain.doFilter() 後,容器會檢查鏈中是否還有下一個過濾器,若有則繼續執行,否則調用目標 Servlet。
執行順序示意:
doFilter 前半段doFilter 前半段service() / doGet()doFilter 後半段doFilter 後半段

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