天天看點

過濾器(filter)在web 中的應用

過濾器(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過濾器。