JavaWeb基礎學習(六)--過濾器Filter
過濾器(Filter)
Filter 的基本功能是對 Servlet 容器呼叫 Servlet 的過程進行攔截,從而在 Servlet 進行響應處理的前後實現一些特殊的功能。
在 Servlet API 中定義了三個介面供開發人員編寫 Filter 程式:Filter, FilterChain, FilterConfig。
Filter 程式是一個實現了 Filter 介面的 Java 類,與 Servlet 程式相似,它由 Servlet 容器進行呼叫和執行。
Filter 程式需要在 web.xml 檔案中進行註冊和設定它所能攔截的資源:Filter 程式可以攔截 Jsp, Servlet, 靜態圖片檔案和靜態 html 檔案
過濾過程:
基本工作原理:
Filter可以對Servlet容器傳送給Servlet程式的請求和Servlet程式傳送給Servlet容器的響應進行攔截,從而對請求和響應的資訊進行過濾。
一個web.xml中可以註冊多個Filter,當有多個Filter對某個Servlet程式的訪問過程進行攔截時,針對該Servlet的訪問到達後,web容器就會把這些Filter組合成一個Filter鏈。鏈中各個Filter的攔截順序與它們在web.xml對映的先後順序一致。
Filter介面:
與開發Servlet不同,Filter介面並沒有相應的實現類可以繼承。因此,要開發過濾器,只能實現Filter介面。實現Filter介面需要重寫下列幾個方法:
- init(FilterConfig filterConfig)throws ServletException;
web應用啟動時,web伺服器會根據web.xml中的配置資訊來建立每個註冊的Filter實
例,並將其儲存在伺服器記憶體中。
web容器建立Filter例項後,立即呼叫init()方法,該方法在該Filter生命週期中只調用一次。
web容器在呼叫init方法時,會傳遞一個包含Filter配置和執行環境的FilterConfig物件。類似於ServletConfig,都由容器實現。利用該物件可以得到ServletContext物件,也可得到Filter配置的初始化引數。該物件的常用方法如下:
- String getFilterName():得到描述符中指定的過濾器的名字。
- String getInitParameter(String name): 返回在部署描述中指定的名字為name的初始化引數的值。如果不存在返回null.
- Enumeration getInitParameterNames():返回過濾器的所有初始化引數的名字的列舉集合。
- public ServletContext getServletContext():返回Servlet上下文物件的引用。
- doFilter(ServletRequest request,ServletResponse response,FilterChain chain) throws IOException,ServletException;
doFilter()類似於Servlet中的service()方法。當客戶端請求目標資源時,容器就會呼叫與
之相關聯的Filter的doFilter()方法。
其中request,response引數為web容器或Filter鏈上一個Filter傳來的請求和響應引數。引數chain為代表當前Filter鏈的物件,只有呼叫該物件的doFilter(request,response)方法之後,才能把請求交付給下一個Filter或目標Servlet去處理。
即通過chain. doFilter(request, response)放行,讓請求和響應向下執行。
該方法的請求和響應引數型別是ServletRequest和ServletResponse,Filter不依賴於具體的協議。
- destroy()
web容器解除安裝Filter物件前呼叫,該方法在Filter生命週期中只調用一次,釋放Filter佔
用的資源。
過濾器的部署:
實現Filter之後,需要在web.xml中註冊和設定Filter攔截的資源。通過<filter></filter>和< filter-mapping></ filter-mapping>元素來完成。
Filter註冊方式與Servlet基本一致,只是部分名稱不同而已。
<filter>
<filter-name>testFitler</filter-name>
<filter-class>org.test.TestFiter</filter-class>
<!-- 配置Filter初始化的引數 -->
<init-param>
<param-name>name</param-name>
<param-value>TestFilter</param-value>
</init-param>
</filter>
<filter-mapping>元素用於設定一個 Filter 所負責攔截的資源。一個Filter攔截的資源可通過兩種方式來指定:Servlet 名稱和資源訪問的請求路徑( url樣式)
- <filter-name>子元素用於設定filter的註冊名稱。該值必須是在<filter>元素中宣告過的過濾器的名字。
- <url-pattern>設定 filter 所攔截的請求路徑。
- <servlet-name>指定過濾器所攔截的Servlet名稱。
- <dispatcher>指定過濾器所攔截的資源被 Servlet 容器呼叫的方式,可以是REQUEST, INCLUDE,FORWARD和ERROR之一,預設REQUEST. 可以設定多個<dispatcher> 子元素用來指定 Filter 對資源的多種呼叫方式進行攔截。
<dispatcher>子元素設定的值及其意義:
REQUEST |
當用戶直接訪問頁面時,Web容器將會呼叫過濾器。 |
INCLUDE |
如果目標資源是通過RequestDispatcher的include()方法訪問時,那麼該過濾器將被呼叫。 |
FORWARD |
如果目標資源是通過RequestDispatcher的forward()方法訪問時,那麼該過濾器將被呼叫。 |
ERROR |
如果目標資源是通過宣告式異常處理機制呼叫時,那麼該過濾器將被呼叫。 |