一、過濾器是什麼?
對web應用來說,過濾器就是駐留在伺服器端、源資料和目的資料之間,對web請求和web響應的頭屬性(Header)和内容體(Body)進行操作的一種特殊的web元件。它們攔截請求和響應。
二、過濾器怎麼工作的?
當web容器收到一個對資源的請求時,容器将判斷是否有過濾器與這個資源有關,如果有,容器把這個請求發給過濾器進行處理,過濾器處理請求後再把請求發送給目标資源。當目标資源對請求作出響應時,響應也會被容器先轉發給過濾器,在過濾器中對響應内容進行處理,然後響應被發送到用戶端。
在一個web應用程式中,可以部署多個過濾器,這些過濾器組成一個過濾器鍊。過濾器鍊中的每個過濾器都有特定的操作,請求和響應在浏覽器和目标資源之間按照部署描述符中聲明的過濾器順序,在過濾器之間進行傳遞。
在請求資源時按照過濾器的順序依次對請求進行處理,并将請求沿過濾器鍊傳遞給下一個過濾器,直到傳遞到目标資源;發送響應則是按照過濾器鍊相反方向對響應進行處理和傳遞,直到把響應傳到用戶端為止。過濾器并不是必須把請求傳送到下一個過濾器,它也可以根據處理結果直接給用戶端發送響應,也可以将請求轉發給另一個目标資源。
三、Filter API
與過濾器開發相關的一些接口和類
1、Filter接口
所有的過濾器在開發中都隻能實作java.servlet.Filter接口。并且提供一個公開的不帶參數的構造方法。接口定義了init()、doFiter()、destroy()3個方法,和servlet接口相似。
(1)public void init(FilterConfig config)throws ServletException
web容器調用init()方法,說明過濾器正在被嵌入到web容器中去。容器隻在執行個體化過濾器時才會調用該方法一次。初始化方法必須在被調用做過濾工作前正确完成。容器為這個方法傳遞一個FilterConfig對象,其中包含着在部署描述符中配置的與過濾器相關的初始化參數。
(2)public void doFiter(ServletRequest req,ServletResponse res,FilterChain chain)throws IOException,ServletException
實作了過濾器對請求和響應的操作功能。每當請求和響應經過過濾器鍊時,容器都要調用一次該方法。FilterChain對象代表了多個過濾器形成的過濾器鍊。為了将請求/響應沿過濾器鍊繼續傳送,在每個過濾器的doFilter()方法中必須調用FilterChain對象的doFilter()方法。
web容器将請求對象,響應對象和過濾器的連結對象3個參數傳遞到該方法。在過濾器中處理的ServletRequest對象和ServletResponse對象,最終要傳遞到被過濾的Servlet和JSP,是以在doFilter()方法中可以通過對ServletRequest的操作在Servlet運作之前改變web請求的頭資訊或内容,通過對ServletResponse的操作在Servlet運作之後改變響應結果。
(3)public void destroy()
web容器調用destroy()方法表示過濾器生命周期結束,在這個方法中釋放過濾器使用的資源。
2、FilterConfig接口
當容器對Filter對象進行初始化時,容器調用Filter的init(),并傳入一個實作FilterConfig接口的對象。Filter可以使用該對象獲得部署檔案中的一些配置資訊。
3、FilterChain接口
這個接口由容器實作,容器将其執行個體作為參數傳入過濾器對象的doFilter()方法中。過濾器對象使用FilterChain對象調用過濾器鍊中的下一個過濾器或者調用目标資源。
FilterChain接口僅定義一個方法:public void doFilter(),該方法用于将請求/響應繼續沿過濾器鍊向後傳送給下一個過濾器。如果調用該方法的過濾器是鍊中最後一個,則調用目标資源。
四、開發部署一個過濾器
1、編寫一個過濾器類
實作Filter接口,然後在doFilter()中寫需要執行的代碼。
2、部署過濾器
①聲明過濾器<filter>
<filter>元素的結構如下:
②設定過濾器映射<filter-mapping>
<filter-mapping>元素結構如下:
配置如下: