教育行業(yè)A股IPO第一股(股票代碼 003032)

全國咨詢/投訴熱線:400-618-4000

filter過濾鏈:Filter鏈?zhǔn)侨绾螛?gòu)建的?

更新時間:2020年09月18日14時56分 來源:傳智播客 瀏覽次數(shù):

在一個Web應(yīng)用程序中可以注冊多個Filter程序,每個Filter程序都可以針對某一個URL進行攔截。如果多個Filter程序都對同一個URL進行攔截,那么這些Filter就會組成一個Filter鏈(也叫過濾器鏈)。Filter鏈用FilterChain對象來表示,F(xiàn)ilterChain對象中有一個doFilter()方法,該方法作用就是讓Filter鏈上的當(dāng)前過濾器放行,請求進入下一個Filter,接下來通過一個圖例來描述Filter鏈的攔截過程,如圖1所示。

filter鏈

圖1 Filter鏈

在圖1中,當(dāng)瀏覽器訪問Web服務(wù)器中的資源時需要經(jīng)過兩個過濾器Filter1和Filter2,首先Filter1會對這個請求進行攔截,在Filter1過濾器中處理好請求后,通過調(diào)用Filter1的doFilter()方法將請求傳遞給Filter2,F(xiàn)ilter2將用戶請求處理后同樣調(diào)用doFilter()方法,最終將請求發(fā)送給目標(biāo)資源。當(dāng)Web服務(wù)器對這個請求做出響應(yīng)時,也會被過濾器攔截,這個攔截順序與之前相反,最終將響應(yīng)結(jié)果發(fā)送給客戶端。

為了讓讀者更好的學(xué)習(xí)Filter鏈,接下來,通過一個案例,分步驟演示如何使用Filter鏈攔截MyServlet的同一個請求,具體如下:

(1)在chapter04工程的cn.itcast.chapter04.filter包中新建MyFilter01和MyFilter02,如例1和2所示。

例1 MyFilter01.java

 1  package cn.itcast.chapter04.filter;

 2  import java.io.*;

 3  import javax.servlet.*;

 4  public class MyFilter01 implements Filter {

 5    public void destroy() {

 6      // 過濾器對象在銷毀時自動調(diào)用,釋放資源

 7    }

 8    public void doFilter(ServletRequest request, ServletResponse response,

 9        FilterChain chain) throws IOException, ServletException {

 10     // 用于攔截用戶的請求,如果和當(dāng)前過濾器的攔截路徑匹配,該方法會被調(diào)用

 11     PrintWriter out=response.getWriter();

 12     out.write("Hello MyFilter01</br>");

 13     chain.doFilter(request, response);

 14   }

 15   public void init(FilterConfig fConfig) throws ServletException {

 16     // 過濾器對象在初始化時調(diào)用,可以配置一些初始化參數(shù)

 17   }

 18 }

例2 MyFilter02.java

1  package cn.itcast.chapter04.filter;

 2  import java.io.*;

 3  import javax.servlet.Filter;

 4  import javax.servlet.*;

 5  public class MyFilter02 implements Filter {

 6    public void destroy() {

 7      // 過濾器對象在銷毀時自動調(diào)用,釋放資源

 8    }

 9    public void doFilter(ServletRequest request, ServletResponse response,

 10       FilterChain chain) throws IOException, ServletException {

 11     // 用于攔截用戶的請求,如果和當(dāng)前過濾器的攔截路徑匹配,該方法會被調(diào)用

 12     PrintWriter out=response.getWriter();

 13     out.write("MyFilter02 Before</br>");

 14     chain.doFilter(request, response);

 15     out.write("</br>MyFilter02 After</br>");  

 16   }

 17   public void init(FilterConfig fConfig) throws ServletException {

 18     // 過濾器對象在初始化時調(diào)用,可以配置一些初始化參數(shù)

 19   }

 20 }

(2)在web.xml文件中將MyFilter01和MyFilter02注冊在MyServlet前面,具體如下所示:

<filter>

  <filter-name>MyFilter01</filter-name>

  <filter-class>cn.itcast.chapter04.filter.MyFilter01</filter-class>

 </filter>

 <filter-mapping>

  <filter-name>MyFilter01</filter-name>

  <url-pattern>/MyServlet</url-pattern>

 </filter-mapping>

 <filter>

  <filter-name>MyFilter02</filter-name>

  <filter-class>cn.itcast.chapter04.filter.MyFilter02</filter-class>

 </filter>

 <filter-mapping>

  <filter-name>MyFilter02</filter-name>

  <url-pattern>/MyServlet</url-pattern>

 </filter-mapping>

 <servlet>

   <servlet-name>MyServlet</servlet-name>

  <servlet-class>cn.itcast.chapter04.filter.MyServlet</servlet-class>

 </servlet>

 <servlet-mapping>

  <servlet-name>MyServlet</servlet-name>

  <url-pattern>/MyServlet</url-pattern>

 </servlet-mapping>

(3)重新啟動Tomcat服務(wù)器,在瀏覽器地址欄中輸入http://localhost:8080/chapter04/MyServlet,此時,瀏覽器窗口中的顯示結(jié)果如圖2所示。

運行結(jié)果

從圖2中可以看出,MyServlet首先被MyFilter01攔截了,打印出MyFilter01中的內(nèi)容,然后被MyFilter02攔截,直到 MyServlet被MyFilter02放行后,瀏覽器才顯示出MySerlvet中的輸出內(nèi)容。

需要注意的是,F(xiàn)ilter鏈中各個Filter的攔截順序與它們在web.xml文件中元素的映射順序一致,由于MyFilter01的元素位于MyFilter02的元素前面,因此用戶的訪問請求首先會被MyFilter01攔截,然后再被MyFilter02攔截。


猜你喜歡:
什么是filter?filter是用來做什么的?

filter映射:filter的兩種映射方式

java高級軟件工程師

0 分享到:
和我們在線交談!