過濾器(Filter)在Web開發中的應用:
Filter是從Servlet2.3規範開始新增的功能,並在Servlet2.4規範中得到增強。以下是
Filter在Web開發中的應用。
過濾器概述:
過濾器就是在源數據和目的數據之間起過濾作用的中間組件。對Web應用來說,過濾器
是一個駐留在服務器端的Web組件,它可以截取客戶端和資源之間的請求與響應信息,
並對這些信息進行過濾。
當Web容器接受到一個對資源的請求時,它將判斷是否有過濾器與這個資源相關聯。如
果有,那麼容器將把請求交給過濾器進行處理。在過濾器中,你可以改變請求的內容,
或者重新設置請求的報頭信息,然後再將請求發送給目標資源。當目標資源對請求作出
響應時候,容器同樣會將響應先轉發給過濾器,再過濾器中,你可以對響應的內容進行
轉換,然後再將響應發送到客戶端。
過濾器在Web開發中的一些主要應用:
·對用戶請求進行統一認證。
·對用戶的訪問請求進行記錄和審覈。
·對用戶發送的數據進行過濾或替換。
·轉換圖象格式。
·對響應內容進行壓縮,減少傳輸量。
·對請求或響應進行加解密處理
·觸發資源訪問是事件。
·對XML的輸出應用XSLT。
Filter API :
與過濾器開發相關的接口與類都包含在javax.serlvet和javax.servlet.http包中,主
要有下面的接口和類。
·javax.servlet.Filter接口
·javax.servlet.FilterConfig接口
·javax.servlet.FilterChain接口
·javax.servlet.ServletRequestWrapper類
·javax.servlet.ServletResponseWrapper類
·javax.servlet.http.HttpServletRequestWrapper類
·javax.servlet.http.HttpServletResponseWrapper類
Filter接口:
開發過濾器要實現javax.servlet.Filter接口,與開發servlet要實現
javax.servlet.Servlet接口類似。提供了一個公開的不帶參數的構造方法。在Filter
接口中,定義了下面的三個方法:
·public void init(FilterConfig filterConfig)throws ServletException
Web容器調用該方法該方法來初始化過濾器。容器在調用該方法時,向過濾器傳遞
FIlterConfig對象,FilterConfig的用法和ServletConfig(參見以前相關內容)類似
。利用FilterConfig對象可以得到ServletContext對象,以及部署描述符中配置的過濾
器的初始化參數。在這個方法中,可以拋出ServletException異常,通知容器該過濾器
不能正常工作。
·public void doFilter(ServletRequest request,ServletResponse
response,FilterChain chain)throws java.io.IOException,ServletException
doFilter()方法類似於Servlet接口的service()方法。當客戶端請求目標資源的時候,
容器就會調用與這個目標資源相關聯的過濾器的doFilter()方法。在特定的操作完成後
,可以調用chain.doFilter(request,response)將請求傳給下一個過濾器(或目標資源
),也可以直接向客戶端返回響應信息,或者利用RequestDispatcher的forward()和
include()方法,以及HttpServletResponse的sendRedirect()方法將請求轉向到其他資
源。需要注意的是,這個方法的請求和響應參數的類型是ServletRequest和
ServletResponse,也就是說,過濾器的使用並不依賴於具體的協議。
·public void destroy()
Web容器調用該方法指示過濾器的生命週期結束。在這個方法中,可以釋放過濾器使用
的資源。
與開發Servlet不同的是,Filter接口並沒有相應的實現類可供繼承,要開發過濾器,
只能直接實現Filter接口。
FilterConfig接口:
javax.servlet.FilterConfig接口類似於javax.servlet.ServletConfig接口,用於在
過濾器初始化時,向其傳遞信息。FilterConfig接口有容器實現,容器將其作爲參數傳
入過濾器對象的init()方法中。在FilterConfig接口,定義了4個方法:
·public java.lang.String getFilterName()
得到描述符中指定的過濾器的名字。
·public java.lang.String getInitParameter(java.lang.String name)
返回在部署描述中指定的名字爲name的初始化參數的值。如果不存在返回null.
·public java.util.Enumeration getInitParameterNames()
返回過濾器的所有初始化參數的名字的枚舉集合。
·public ServletContext getServletContext()
返回Servlet上下文對象的引用。
FilterChain接口:
FilterChain接口由容器實現,容器將其實例作爲參數傳入過濾器對象的doFilter()方
法中。過濾器對象使用FilterChain對象調用過濾器鏈中的下一個過濾器,如果該過濾
器是鏈中最後一個過濾器,那麼將調用目標資源。FilterChain接口只有一個方法,如
下:
·public void doFilter(ServletRequest request,ServletResponse response)
throws java.io.IOException
調用該方法將使過濾器鏈中的下一個過濾器被調用。如果是最後一個過濾器,會調用目
標資源。
過濾器的部署:
在實現一個過濾器後,需要在部署描述符中對過濾器進行配置,這是通過<filter>和
<filter-mapping>元素來完成的。
<filter>元素用於在Web應用程序中聲明一個過濾器。
在<filter>元素內,<description>、<display-name>、<icon>元素和以往servlet的配
置中的相同。<filter-name>用於爲過濾器指定一個名字,該元素的內容不能爲空。
<filter-class>元素用於指定過濾器的完整的限定類名。<init-param>元素用於爲過濾
器指定初始化參數,它的子元素<param-name>指定參數的名字,<param-value>指定參
數的值。在過濾器中,可以使用FilterConfig接口對象來訪問初始化參數。
下面是<filte>元素的一個小例子:
<filter>
<filter-name>testFitler</filter-name>
<filter-class>org.test.TestFiter</filter-class>
<init-param>
<param-name>word_file</param-name>
<param-value>/WEB-INF/word.txt</param-value>
</init-param>
</filter>
Servlet容器對部署描述符中聲明的每一個過濾器,只創建一個實例。與Servlet類似,
容器將在同一個過濾器實例上運行多個線程來同時爲多個請求服務,因此,開發過濾器
時,也要注意線程安全的問題。
<filter-mapping>元素用於指定過濾器關聯的url樣式或者Servlet。
其中<filter-name>子元素的值必須是在<filter>元素中聲明過的過濾器的名字。<url-pattern>元素和<servlet-name>元素可以選擇一個;<url-pattern>元素指定過濾器關聯的URL樣式;<servlet-name>元素指定過濾器對應的Servlet。用戶在訪問<url-pattern>元素指定的URL上的資源或<servlet-name>元素指定的Servlet時,該過濾器纔會被容器調用。<filter-mapping>元素還可以包含0到4個<dispatcher>,指定過濾器對應的請求方式,可以是REQUEST,INCLUDE,FORWARD和ERROR之一,默認REQUEST.
·REQUEST
當用戶直接訪問也面時,Web容器將會調用過濾器。如果目標資源是通過RequestDispatcher的include()或forward()方法訪問時,那麼該過濾器就不會被調用。
·INCLUDE
如果目標資源是通過RequestDispatcher的include()方法訪問時,那麼該過濾器將被調用。除此之外,該過濾器不會被調用。
·FORWARD
如果目標資源是通過RequestDispatcher的forward()方法訪問時,那麼該過濾器將被調用,除此之外,該過濾器不會被調用。
·ERROR
如果目標資源是通過聲明式異常處理機制調用時,那麼該過濾器將被調用。除此之外,過濾器不會被調用。
例子:
<filter-mapping>
<filter-name>testFilter</filter-name>
<url-pattern>/test.jsp</url-pattern>
</filter-mapping>
當用戶訪問test.jsp頁面時,容器就會調用testFilter過濾器。
<filter-mapping>
<filter-name>testFilter</filter-name>
<url-pattern>/index.jsp</url-pattern>
<dispatcher>REQUEST</dispatcher>
<dispatcher>FORWARD</dispatcher>
</filter-mapping>
當用戶直接訪問index.jsp頁面,或者通過RequestDispatcher的forward()方法訪問時,容器就會調用testFilter過濾器。