JavaWeb基礎總結:Filter專題
Java Servlet Filter
Filter 被稱為過濾器,其主要作用是對 Servlet 容器調用 Servlet 的過程進行攔截,從而在 Servlet 進行響應處理的前后實現一些特殊功能。就像人們在生活中使用污水凈化設備對水源進行過濾凈化,在程序中,可以使用 Filter 對請求和響應信息進行過濾。Filter具體的作用位置及流程如下圖:

當用戶通過瀏覽器訪問服務器中的目標資源時,首先會被 Filter 攔截,在 Filter 中進行預處理操作,然后再將請求轉發給目標資源。當服務器接收到這個請求后會對其進行響應,在服務器處理響應的過程中,也需要將響應結果經過濾器處理后,才發送給客戶端。
Filter 過濾器就是一個實現了 javax.servlet.Filter 接口的類,在 javax.servlet.Filter 接口中定義了三個方法
| 方法聲明 | 功能描述 |
|---|---|
| init(FilterConfig filterConfig) | init() 方法用于初始化過濾器,開發人員可以在 init() 方法中完成與構造方法類似的初始化功能,如果初始化代碼中要使用到 FillerConfig 對象,那么,這些初始化代碼就只能在 Filler 的 init() 方法中編寫,而不能在構造方法中編寫 |
| doFilter(ServletRequest request,SeivletResponse response, FilterChain chain) |
doFilter() 方法有多個參數,其中,參數 request 和 response 為 Web 服務器或 Filter 鏈中的上一個 Filter 傳遞過來的請求和響應對象; 參數 chain 代表當前 Filter 鏈的對象,只有在當前 Filter 對象中的 doFilter() 方法內部需要調用 FilterChain 對象的 doFilter() 方法,才能把請求交付給 Filter 鏈中的下一個 Filter 或者目標程序處理 |
| destroy() | destroy() 方法在 Web 服務器卸載 Filter 對象之前被調用,該方法用于釋放被 Filter 對象打開的資源,例如關閉數據庫和 I/O 流 |
表中的三個方法都是可以表現 Filter 生命周期的方法,其中 init() 方法在 Web 應用程序加載時會被調用,destroy() 方法在 Web 應用程序卸載(或關閉)時被調用,這兩個方法都只會被調用一次,而 doFilter() 方法會被調用多次(只要客戶端有請求時就會被調用),Filter 所有的工作集中在 doFilter() 方法中。
Filter的映射配置
Filter的控制一般通過配置文件來實現,在 web.xml 中的對應配置信息就是 Filter 映射。Filter 的映射方式可分為兩種。
使用通配符*攔截用戶的所有請求
Filter 的 <filter-mapping> 元素用于配置過濾器攔截的資源信息,如果想讓過濾器攔截所有的請求,那么可以使用通配符*實現,具體實現方式如下:
<filter> <filter-name>OneFilter</filter-name> <filter-class>com.mengma.filter.OneFilter</filter-class> </filter> <filter-mapping> <filter-name>OneFilter</filter-name> <url-pattern>/*</url-pattern> </filter-mapping>
攔截不同方式的訪問請求
在 web.xml 文件中,每一個 <filter-mapping> 元素都可以配置一個 Filter 所負責攔截的資源。在 <filter-mapping> 元素中有一個特殊的子元素 <dispatcher>,該元素用于指定過濾器所攔截的資源被 Servlet 容器調用的方式。例:
<filter> <filter-name>ForwardFilter</filter-name> <filter-class>com.mengma.filter.ForwardFilter</filter-class> </filter> <filter-mapping> <filter-name>ForwardFilter</filter-name> <url-pattern>/first.jsp</url-pattern> <dispatcher>FORWARD</dispatcher> </filter-mapping>
<dispatcher> 元素的參數值共有4個,詳細如下表:
| 名稱 | 功能描述 |
|---|---|
| REQUEST | 當用戶直接訪問頁面時,Web 容器將會調用過濾器。如果目標資源通過 RequestDispatcher 的 include() 或 forward() 方法訪問,那么該過濾器將不會被調用 |
| INCLUDE | 如果目標資源通過 RequestDispatcher 的 include() 方法訪問,那么該過濾器將會被調用。除此之外,該過濾器不會被調用 |
| FORWARD | 如果目標資源通過 RequestDispatcher 的 forward() 方法訪問,那么該過濾器將會被調用。除此之外,該過濾器不會被調用 |
| ERROR | 如果目標資源通過聲明式異常處理機制調用,那么該過濾器將會被調用。除此之外,該過濾器不會被調用 |
FilterChain(過濾器鏈)
在一個 Web 應用程序中可以注冊多個 Filter 程序,每個 Filter 程序都可以針對某一個 URL 進行攔截。如果多個 Filter 程序都對同一個 URL 進行攔截,那么這些 Filter 就會組成一個Filter 鏈(也稱過濾器鏈)。
Filter 鏈用 FilterChain 對象表示,FilterChain 對象中有一個 doFilter() 方法,該方法的作用是讓 Filter 鏈上的當前過濾器放行,使請求進入下一個 Filter。

當瀏覽器訪問 Web 服務器中的資源時,需要經過兩個過濾器 Filter1 和 Filter2。首先 Filter1 會對這個請求進行攔截,在 Filter1 中處理完請求后,通過調用 Filter1 的 doFilter() 方法將請求傳遞給 Filter2,Filter2 處理用戶請求后同樣調用 doFilter() 方法,最終將請求發送給目標資源。當 Web 服務器對這個請求做出響應時,也會被過濾器攔截,但這個攔截順序與之前相反,最終將響應結果發送給客戶端瀏覽器。過濾鏈的具體實現原理大家可以看 設計模式——責任鏈

浙公網安備 33010602011771號