更新時間:2020年09月18日14時56分 來源:傳智播客 瀏覽次數(shù):
在一個Web應用程序中可以注冊多個Filter程序,每個Filter程序都可以針對某一個URL進行攔截。如果多個Filter程序都對同一個URL進行攔截,那么這些Filter就會組成一個Filter鏈(也叫過濾器鏈)。Filter鏈用FilterChain對象來表示,F(xiàn)ilterChain對象中有一個doFilter()方法,該方法作用就是讓Filter鏈上的當前過濾器放行,請求進入下一個Filter,接下來通過一個圖例來描述Filter鏈的攔截過程,如圖1所示。
圖1 Filter鏈
在圖1中,當瀏覽器訪問Web服務器中的資源時需要經(jīng)過兩個過濾器Filter1和Filter2,首先Filter1會對這個請求進行攔截,在Filter1過濾器中處理好請求后,通過調用Filter1的doFilter()方法將請求傳遞給Filter2,F(xiàn)ilter2將用戶請求處理后同樣調用doFilter()方法,最終將請求發(fā)送給目標資源。當Web服務器對這個請求做出響應時,也會被過濾器攔截,這個攔截順序與之前相反,最終將響應結果發(fā)送給客戶端。
為了讓讀者更好的學習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 // 過濾器對象在銷毀時自動調用,釋放資源
7 }
8 public void doFilter(ServletRequest request, ServletResponse response,
9 FilterChain chain) throws IOException, ServletException {
10 // 用于攔截用戶的請求,如果和當前過濾器的攔截路徑匹配,該方法會被調用
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 // 過濾器對象在初始化時調用,可以配置一些初始化參數(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 // 過濾器對象在銷毀時自動調用,釋放資源
8 }
9 public void doFilter(ServletRequest request, ServletResponse response,
10 FilterChain chain) throws IOException, ServletException {
11 // 用于攔截用戶的請求,如果和當前過濾器的攔截路徑匹配,該方法會被調用
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 // 過濾器對象在初始化時調用,可以配置一些初始化參數(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服務器,在瀏覽器地址欄中輸入http://localhost:8080/chapter04/MyServlet,此時,瀏覽器窗口中的顯示結果如圖2所示。
從圖2中可以看出,MyServlet首先被MyFilter01攔截了,打印出MyFilter01中的內容,然后被MyFilter02攔截,直到 MyServlet被MyFilter02放行后,瀏覽器才顯示出MySerlvet中的輸出內容。
需要注意的是,F(xiàn)ilter鏈中各個Filter的攔截順序與它們在web.xml文件中元素的映射順序一致,由于MyFilter01的元素位于MyFilter02的元素前面,因此用戶的訪問請求首先會被MyFilter01攔截,然后再被MyFilter02攔截。
猜你喜歡:
什么是filter?filter是用來做什么的?