多個Filter按照在配置文件中配置的filter順序執行。html
在web.xml文件中配置該Filter,使用init-param元素爲該Filter配置參數,init-param可接受以下兩個子元素:java
param-name:指定參數名。web
param-value:指定參數值。緩存
filter 、filter-mapping 、servlet、servlet-mapping 才構成一個完整的攔截器配置。服務器
Filter類須要實現Filter接口,該接口有init、doFilter、destroy3個方法,,3個方法順序執行。app
Filter也稱之爲過濾器,它是Servlet技術中比較激動人心的技術,WEB開發人員經過Filter技術,對web服務器管理的全部web資源:例如Jsp, Servlet, 靜態圖片文件或靜態 html 文件等進行攔截,從而實現一些特殊的功能。例如實現URL級別的權限訪問控制、過濾敏感詞彙、壓縮響應信息等一些高級功能。jsp
2、Filter簡介
Servlet API中提供了一個Filter接口,開發web應用時,若是編寫的Java類實現了這個接口,則把這個java類稱之爲過濾器Filter。經過Filter技術,開發人員能夠實現用戶在訪問某個目標資源以前,對訪問的請求和響應進行攔截。簡單說,就是能夠實現web容器對某資源的訪問前截獲進行相關的處理,還能夠在某資源向web容器返回響應前進行截獲進行處理。
3、快速入門
一、新建一個類,實現Filter接口
二、實現doFilter()方法,打印一句話,來證實可以進行攔截
三、在web.xml中進行配置(參照Servlet配置)
四、訪問一個頁面,看看能不能攔截
1>
[java] view plaincopy
package com.test.filter;
import java.io.IOException;
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 Demo1Filter implements Filter {
private FilterConfig filterConfig;
public void doFilter(ServletRequest request, ServletResponse response,
FilterChain chain) throws IOException, ServletException {
System.out.println("Demo1過濾前");
System.out.println(filterConfig.getInitParameter("param1"));
chain.doFilter(request, response);//放行。讓其走到下個鏈或目標資源中
System.out.println("Demo1過濾後");
}
public void init(FilterConfig filterConfig) throws ServletException {
System.out.println("初始化了");
this.filterConfig = filterConfig;
}
public void destroy() {
System.out.println("銷燬了");
}
}
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> 網站
4、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流進行壓縮下。
5、Filter實現攔截的原理
Filter接口中有一個doFilter方法,當開發人員編寫好Filter類實現doFilter方法,並配置對哪一個web資源進行攔截後,WEB服務器每次在調用web資源的service方法以前(服務器內部對資源的訪問機制決定的),都會先調用一下filter的doFilter方法。
6、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方法只會直接一次。
7、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那麼則會攔截,不然不會攔截。this
轉,被屢次轉了,找不到原出處。編碼