隨筆 - 0, 文章 - 75, 評論 - 0, 引用 - 0
          數據加載中……

          過濾器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 體系結構


          Filter并不是從真正意義上對來自客戶端的請求做出最終響應,而是進行部分的過濾工作,對請求數據進行檢測或者安全性檢查等工作。


          Filter只有在客戶端請求或者發出響應時才會自動進行調用,所以沒有必要把這些Filter字節嵌入到整個Web應用系統的框架中,而是通過配置文件來設定。


          當然,大部分情況下,并不需要給Web應用程序設置Filter,因為它不是必需的。如果需要設置Filter,除了可以設置單個Filter關聯外,還可以設置Web應用程序與一個Filter鏈(多個單Filter相串聯)相關聯。


          Filter的工作過程的相關步驟:



          • 首先,通過部署描述器web.xml中對Filter的配置,特定Filter會捕捉到客戶端的請求信息。
          • Filter調用內置方法來檢查捕獲到的請求對象,根據分析結果來決定是把該請求傳遞給下一個Filter(如果存在另一個Filter的話),還是中止該請求并向客戶端發出一個響應。如果不存在Filter鏈,即僅僅為單個Filter,則上一個Filter直接把客戶請求轉發給Web服務器進行相應處理。

          • 如果CSS應用程序關聯了Filter,在客戶端請求設法通過各個Filter被服務器處理時,最終的響應將以相反的順序通過Filter鏈,最后發送給客戶端。

          Filter 基本工作原理



          當在 web.xml 中注冊了一個 Filter 來對某個 Servlet 程序進行攔截處理時,這個 Filter 就成了 Servlet 容器與該
          Servlet 程序的通信線路上的一道關卡,該 Filter 可以對 Servlet 容器發送給 Servlet 程序的請求和 Servlet 程序回送給
          Servlet 容器相應進行攔截,可以決定是否將請求繼續傳遞給 Servlet 程序,以及對請求和相應信息是否進行修改。


          在一個 web 應用程序中可以注冊多個 Filter 程序,每個 Filter 程序都可以對一個或一組 Servlet 程序進行攔截。


          若有多個 Filter 程序對某個 Servlet 程序的訪問過程進行攔截,當針對該 Servlet 的訪問請求到達時,web 容器將把多個 Filter
          程序組合成一個 Filter 鏈(過濾器鏈)。Filter 鏈中各個 Filter 的攔截順序與它們在應用程序的 web.xml 中映射的順序一致。


          Filter的實現步驟


          實現一個Filter的三個步驟:



          • 首先編寫Filter的實現類程序。
          • 其次,需要把實現的Filter添加到Web應用程序中,也就是說,需要在Web部署描述文件Web.xml中聲明該Filter。
          • 最后,將相關聯的Filter與應用程序一起打包并部署。

          Filter的主要作用及Filter API



          Filter的主要作用



          • 對用戶請求進行統一認證
          • 對用戶的訪問請求進行記錄和審核
          • 對用戶發送的數據進行過濾和替換
          • 轉換圖象格式
          • 對響應內容進行壓縮,減少傳輸量
          • 對請求或響應進行加解密處理
          • 觸發資源訪問事件
          • 對XML的輸出應用XSLT

          Filter API


          與Filter開發相關的接口與類都包含在javax.servlet和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接口



          開發Filter要實現javax.servlet.Filter接口,與開發Servlet要實現javax.servlet.Servlet接口類似。提供了一個公開的不帶參數的構造方法。


          在Filter接口中,定義了下面三個方法。



          Filter接口的方法


          public void init(FilterConfig filterConfig) throws
          ServletException


          在 web 應用程序啟動時,web 服務器將根據 web.xml 文件中的配置信息來創建每個注冊的 Filter
          實例對象,并將其保存在服務器的內存中。Web容器創建 Filter 對象實例后,將立即調用該 Filter 對象的 init 方法。Init 方法在
          Filter 生命周期中僅執行一次,web 容器在調用 init 方法時,會傳遞一個包含 Filter 的配置和運行環境的 FilterConfig
          對象(FilterConfig的用法和ServletConfig類似)。利用FilterConfig對象可以得到ServletContext對象,以及部署描述符中配置的過濾器的初始化參數。在這個方法中,可以拋出ServletException異常,通知容器該過濾器不能正常工作。


          public void doFilter(ServletRequest request,ServletResponse
          response,FilterChain chain) throws IOException,ServletException


          doFilter()方法類似于Servlet接口的service()方法。當客戶端請求目標資源的時候,容器就會調用與這個目標資源相關聯的過濾器的
          doFilter()方法。其中參數 request, response 為 web 容器或 Filter 鏈的上一個 Filter
          傳遞過來的請求和相應對象;參數 chain 為代表當前 Filter 鏈的對象,在特定的操作完成后,可以調用 FilterChain 對象的
          chain.doFilter(request,response)方法將請求交付給 Filter 鏈中的下一個 Filter 或者目標 Servlet
          程序去處理,也可以直接向客戶端返回響應信息,或者利用RequestDispatcher的forward()和include()方法,以及
          HttpServletResponse的sendRedirect()方法將請求轉向到其他資源。這個方法的請求和響應參數的類型是
          ServletRequest和ServletResponse,也就是說,過濾器的使用并不依賴于具體的協議。


          public void destroy()


          Web容器調用該方法指示Filter的生命周期結束。在這個方法中,可以釋放Filter使用的資源。



          與開發Servlet不同的是,Filter接口并沒有相應的實現類可供繼承,要開發過濾器,只能直接實現Filter接口。


          FilterChain接口



          代表當前 Filter
          鏈的對象,由容器實現,容器將其實例作為參數傳入過濾器對象的doFilter()方法中。過濾器對象使用FilterChain對象調用過濾器鏈中的下一個過濾器,如果該過濾器是鏈中最后一個過濾器,那么將調用目標資源。


          FilterChain接口只有一個方法。



          FilterChain接口的方法


          public void doFilter(ServletRequest request,ServletResponse response)
          throws IOException


          調用該方法將使過濾器鏈中的下一個過濾器被調用。如果是最后一個過濾器,會調用目標資源。


          FilterConfig接口



          javax.servlet.FilterConfig接口類似于javax.servlet.ServletConfig接口,用于在Filter初始化時向其傳遞信息。FilterConfig接口有容器實現,容器將其作為參數傳入Filter對象的init()方法中。


          在FilterConfig接口中,定義了四個方法。



          FilterConfig接口的方法


          public String getFilterName()


          得到描述符中指定的過濾器的名字。


          public String getInitParameter(String name)


          返回在部署描述中指定的名字為name的初始化參數的值。如果不存在返回null。


          public Enumeration getInitParameterNames()


          返回過濾器的所有初始化參數的名字的枚舉集合。


          public ServletContext getSerlvetContext()


          返回Servlet上下文對象的引用


          Filter的部署



          在實現一個Filter后,需要在部署描述符中對Filter進行配置,這是通過<filter>和<filter-mapping>元素來完成的。



          <filter>元素


          用于在Web應用程序中聲明一個Filter。


          在<filter>元素內,<description>、<display-name>、<icon>元素和以往serlvet的配置中的相同。



          • <filter-name>用于為Filter指定一個名稱,該元素的內容不能為空。
          • <filter-class>元素用于指定Filter的完整的限定類名。
          • <init-param>元素用于為Filter指定初始化參數。它的子元素<param-name>指定參數的名稱;<param-value>指定參數的值。

          在Filter中,可以使用FilterConfig接口對象來訪問初始化參數。



          <filter-mapping>元素


          用于指定Filter關聯的url樣式或者Servlet。



          • <filter-name>子元素的值必須是在<filter>元素中聲明過的Filter的名字。
          • <url-pattern>元素指定Filter關聯的URL樣式。
          • <servlet-name>元素指定Filter對應的Servlet。

          <url-pattern>元素和<servlet-name>元素可以選擇一個;用戶在訪問<url-pattern>元素指定的URL上的資源或<servlet-name>元素指定的Servlet時,該Filter才會被容器調用。



          -------------------------------


          Filter演示示例



          創建一個簡單的Filter(TimeTrackFilter.java),跟蹤滿足一個客戶機的Web請求大致所花的時間。



          創建Filter


          TimeTrackFilter.java

          package cn.jbit.auction.servlet; import java.io.IOException; import java.util.Date; import javax.servlet.Filter; import javax.servlet.FilterChain; import javax.servlet.FilterConfig; import javax.servlet.ServletException; import javax.servlet.ServletRequest; import javax.servlet.ServletResponse; public class TimeTrackFilter implements Filter { private FilterConfig filterConfig = null; // 初始化Filter public void init(FilterConfig filterConfig) throws ServletException { // TODO Auto-generated method stub this.filterConfig = filterConfig; } // 執行Filter功能 public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException { // TODO Auto-generated method stub Date startTime,endTime; double totalTime; startTime = new Date(); // 把處理發送到下一個Filter chain.doFilter(request, response); // 接下來的語句就是處理請求的過程:計算開始到結束的時間 endTime = new Date(); totalTime = endTime.getTime()-startTime.getTime(); totalTime = totalTime / 1000; System.out.println("============================="); System.out.println("Total elapsed time is: " + totalTime + " seconds."); System.out.println("============================="); filterConfig.getServletContext(); } public void destroy() { // TODO Auto-generated method stub this.filterConfig = null; } }


          配置Filter


          實現了Filter后,還需要通過web.xml文件中的兩上XML元素來聲明該Filter。


          配置web.xml

          <filter> <filter-name>requestTimer</filter-name> <filter-class>cn.jbit.auction.servlet.TimeTrackFilter</filter-class> </filter> <filter-mapping> <filter-name>requestTimer</filter-name> <url-pattern>/*</url-pattern> </filter-mapping>

          posted on 2012-04-22 15:56 hantai 閱讀(139) 評論(0)  編輯  收藏


          只有注冊用戶登錄后才能發表評論。


          網站導航:
           
          主站蜘蛛池模板: 浦县| 杨浦区| 大悟县| 肃南| 平原县| 长治县| 中山市| 辽宁省| 崇左市| 临潭县| 富锦市| 修武县| 双江| 荥阳市| 怀来县| 漳州市| 淅川县| 沙洋县| 峨眉山市| 三明市| 普陀区| 乌兰浩特市| 博罗县| 锦屏县| 永仁县| 渑池县| 池州市| 海伦市| 柯坪县| 玉门市| 名山县| 于田县| 新化县| 北宁市| 高阳县| 金寨县| 郁南县| 关岭| 崇明县| 新余市| 夏邑县|