、概念:
Filter也稱之為過濾器,它是Servlet技術中比較激動人心的技術,WEB開發人員通過Filter技術,對web伺服器管理的所有web資源:
例如Jsp, Servlet, 靜態圖片檔案或靜態 html
檔案等進行攔截,從而實現一些特殊的功能。例如實現URL級別的許可權訪問控制、過濾敏感詞彙、壓縮響應資訊等一些高階功能。
二、Filter簡介
Servlet
API中提供了一個Filter介面,開發web應用時,如果編寫的Java類實現了這個介面,則把這個java類稱之為過濾器Filter。通過
Filter技術,開發人員可以實現使用者在訪問某個目標資源之前,對訪問的請求和響應進行攔截。簡單說,就是可以實現web容器對某資源的訪問前截獲進行
相關的處理,還可以在某資源向web容器返回響應前進行截獲進行處理。
三、快速入門
1、新建一個類,實現Filter介面
2、實現doFilter()方法,列印一句話,來證明能夠進行攔截
3、在web.xml中進行配置(參照Servlet配置)
4、訪問一個頁面,看看能不能攔截
1>
[java] view plaincopy
1 package com.test.filter; 2 3 import java.io.IOException; 4 import javax.servlet.Filter; 5 import javax.servlet.FilterChain; 6 import javax.servlet.FilterConfig; 7 import javax.servlet.ServletException; 8 import javax.servlet.ServletRequest; 9 import javax.servlet.ServletResponse; 10 public class Demo1Filter implements Filter { 11 private FilterConfig filterConfig; 12 13 public void doFilter(ServletRequest request, ServletResponse response, 14 FilterChain chain) throws IOException, ServletException { 15 System.out.println("Demo1過濾前"); 16 System.out.println(filterConfig.getInitParameter("param1")); 17 chain.doFilter(request, response);//放行。讓其走到下個鏈或目標資源中 18 System.out.println("Demo1過濾後"); 19 } 20 21 public void init(FilterConfig filterConfig) throws ServletException { 22 System.out.println("初始化了"); 23 this.filterConfig = filterConfig; 24 } 25 26 public void destroy() { 27 System.out.println("銷燬了"); 28 } 29 }
2>在web.xml中進行配置
[html] view plaincopy
<filter> <filter-name>Demo1Filter</filter-name> <filter-class>com.itheima.filter.Demo1Filter</filter-class> <init-param> <param-name>param1</param-name> <param-value>value在這裡呢</param-value> </init-param> </filter> <filter-mapping> <filter-name>Demo1Filter</filter-name> <url-pattern>/*</url-pattern> <dispatcher>REQUEST</dispatcher> <!-- 沒有配置dispatcher就是預設request方式的 --> <dispatcher>FORWARD</dispatcher> <dispatcher>ERROR</dispatcher> <dispatcher>INCLUDE</dispatcher> </filter-mapping>
四、Filter的應用場景
通過對filter過濾器的瞭解,可以得知在以下三種情況下可以做些處理:
1> 通過控制對chain.doFilter的方法的呼叫,來決定是否需要訪問目標資源。
比如,可以在使用者許可權驗證等等。判斷使用者是否有訪問某些資源的許可權,有許可權放行,沒許可權不執行chain.doFilter方法。
2> 通過在呼叫chain.doFilter方法之前,做些處理來達到某些目的。
比如,解決中文亂碼的問題等等。可以在doFilter方法前,執行設定請求編碼與響應的編碼。甚至可以對request介面進行封裝裝飾來處理get請求方式的中文亂碼問題(重寫相應的request.getParameter方法)。
3> 通過在呼叫chain.doFilter方法之後,做些處理來達到某些目的。
比如對整個web網站進行壓縮。在呼叫chain.doFilter方法之前用類A對response物件進行封裝裝飾,重寫
getOutputStream和重寫getWriter方法。在類A內部中,將輸出內容快取進ByteArrayOutputStream流中,然後在
chain.doFilter方法執行後,獲取類A中ByteArrayOutputStream流快取資料,用GZIPOutputStream流進行
壓縮下。
五、Filter實現攔截的原理
Filter介面中有一個doFilter方法,當開發人員編寫好Filter類實現doFilter方法,並配置對哪個web資源進行攔截後,WEB服
務器每次在呼叫web資源的service方法之前(伺服器內部對資源的訪問機制決定的),都會先呼叫一下filter的doFilter方法。
六、Filter生命週期
和Servlet一樣Filter的建立和銷燬也是由WEB伺服器負責。不過與Servlet區別的是,它是1>在應用啟動的時候就進行裝載
Filter類(與Servlet的load-on-startup配置效果相同)。2>容器建立好Filter物件例項後,呼叫init()方
法。接著被Web容器儲存進應用級的集合容器中去了等待著,使用者訪問資源。3>當使用者訪問的資源正好被Filter的url-pattern攔截
時,容器會取出Filter類呼叫doFilter方法,下次或多次訪問被攔截的資源時,Web容器會直接取出指定Filter物件例項呼叫
doFilter方法(Filter物件常駐留Web容器了)。4>當應用服務被停止或重新裝載了,則會執行Filter的destroy方
法,Filter物件銷燬。
注意:init方法與destroy方法只會直接一次。
七、Filter部署應用注意事項
1> filter-mapping標籤中servlet-name與url-pattern。
Filter不僅可以通過url-pattern來指定攔截哪些url匹配的資源。而且還可以通過servlet-name來指定攔截哪個指定的servlet(專門為某個servlet服務了,servlet-name對應Servlet的相關配置)。
2> filter-mapping標籤中dispatcher。
指定過濾器所攔截的資源被 Servlet
容器呼叫的方式,可以是REQUEST,INCLUDE,FORWARD和ERROR之一,預設REQUEST。使用者可以設定多
個<dispatcher> 子元素用來指定 Filter 對資源的多種呼叫方式進行攔截。
REQUEST:
當使用者直接訪問頁面時,Web容器將會呼叫過濾器。如果目標資源是通過RequestDispatcher的include()或forward()方法訪問或ERROR情況時,那麼該過濾器就不會被呼叫。
INCLUDE:
如果目標資源是通過RequestDispatcher的include()方法訪問時,那麼該過濾器將被呼叫。除此之外,該過濾器不會被呼叫。
FORWARD:
如果目標資源是通過RequestDispatcher的forward()方法訪問時,那麼該過濾器將被呼叫,除此之外,該過濾器不會被呼叫。
ERROR:
如若在A.jsp頁面page指令中指定了error屬性=examError.jsp,那麼A.jsp中若出現了異常,會跳轉到examError.jsp中處理。而在跳轉到examError.jsp時,若過濾器配置了ERROR的dispather那麼則會攔截,否則不會攔截。