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

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

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

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

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

filter鏈

圖1 Filter鏈

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

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

(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      // 過濾器對(duì)象在銷毀時(shí)自動(dòng)調(diào)用,釋放資源

 7    }

 8    public void doFilter(ServletRequest request, ServletResponse response,

 9        FilterChain chain) throws IOException, ServletException {

 10     // 用于攔截用戶的請(qǐng)求,如果和當(dāng)前過濾器的攔截路徑匹配,該方法會(huì)被調(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     // 過濾器對(duì)象在初始化時(shí)調(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      // 過濾器對(duì)象在銷毀時(shí)自動(dòng)調(diào)用,釋放資源

 8    }

 9    public void doFilter(ServletRequest request, ServletResponse response,

 10       FilterChain chain) throws IOException, ServletException {

 11     // 用于攔截用戶的請(qǐng)求,如果和當(dāng)前過濾器的攔截路徑匹配,該方法會(huì)被調(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     // 過濾器對(duì)象在初始化時(shí)調(diào)用,可以配置一些初始化參數(shù)

 19   }

 20 }

(2)在web.xml文件中將MyFilter01和MyFilter02注冊(cè)在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)重新啟動(dòng)Tomcat服務(wù)器,在瀏覽器地址欄中輸入http://localhost:8080/chapter04/MyServlet,此時(shí),瀏覽器窗口中的顯示結(jié)果如圖2所示。

運(yùn)行結(jié)果

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

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


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

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

java高級(jí)軟件工程師

0 分享到:
和我們?cè)诰€交談!