Filter可以擔任瀏覽器與JSP/Servlet之間的一個中介處理者,一些request的前置處理動作及一些response的後置處理,都可以
交由這個中介處理者來完成,當然Filter可以達到的功能,您也可以直接撰寫在JSP/Servlet中,但如果有很多JSP/Servlet都需要相
同的處理,例如某些網頁都需要統一的身份驗證方式時,與其在每一個網頁中都撰寫驗證的程式碼,不如直接撰寫Filter,讓它來統一進行處理。
Filter實際上是一個純綷的Java類別程式,它要實作javax.servlet.Filter介
面,這個介面中有三個必須實作的方法:init()、destory()與doFilter()。init()是Filter類別被載入時會執行的方法,
而destory()是
Filter物件生命週期結束時會執行的方,至於doFilter()則是實作Filter功能的核心,您想要Filter完成的工作就撰寫在其中,先來
撰寫一個簡單的Filter類,如下:
package onlyfun.caterpillar; import java.io.*; import javax.servlet.*; import javax.servlet.http.*; public class FilterDemo1 implements Filter { public void init(FilterConfig config) throws ServletException { } public void destroy() { } public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException { PrintWriter out = response.getWriter(); out.println("Filter 1 is doing!!!"); chain.doFilter(request, response); out.println("Filter 1's work is done"); } }
在這個程式中,只是簡單的顯示一些文字,表示Filter的doFilter()方法有被執行,doFilter()傳入三個參數,
ServletRequest、ServletResponse、FilterChain,您可以獲得request與response物件,以對它們進
行一些處理,像是設定標頭、編碼格式或包裝壓縮功能等等,至於FilterChain則是關於Filter執行順序的物件,這個順序是設定在
web.xml中,您必須呼叫它的doFilter()方法,才可以執行下一個Filter,如果是最後一個Filter,則執行客戶端所請求的
JSP/Servlet網頁。
為了要能使用Filter,您必須在web.xml中撰寫一些設定,一個設定範例如下:
... <filter> <filter-name>FilterDemo1</filter-name> <filter-class>onlyfun.caterpillar.FilterDemo1</filter-class> </filter>
<filter-mapping> <filter-name>FilterDemo1</filter-name> <url-pattern>/*</url-pattern> </filter-mapping> ...
<filter>與</filter>之間撰寫Filter的名稱與實際載入的類別,Filter類別檔是放置在WEB-
INF/classes/下,而<filter-mapping>與</filter-
mapping>之間則撰寫Filter名稱與所要過濾的資源對象,在這邊設定為/*,表示請求這個Web應用程式下的所有資源,都要先經過
Filter的處理。
如果設定的<url-pattern>套用了兩個Filter,則FilterChain在執行doFilter()方法時,其呼叫的 Filter順序就是您在web.xml中撰寫Filter的順序,例如再撰寫一個Filter程式:
package onlyfun.caterpillar; import java.io.*; import javax.servlet.*; import javax.servlet.http.*; public class FilterDemo2 implements Filter { public void init(FilterConfig config) throws ServletException { } public void destroy() { } public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException { PrintWriter out = response.getWriter(); out.println("Filter 2 is doing!!!"); chain.doFilter(request, response); out.println("Filter 2's work is done"); } }
web.xml中設定的內容是:
... <filter> <filter-name>FilterDemo1</filter-name> <filter-class>onlyfun.caterpillar.FilterDemo1</filter-class> </filter>
<filter-mapping> <filter-name>FilterDemo1</filter-name> <url-pattern>/*</url-pattern> </filter-mapping>
<filter> <filter-name>FilterDemo2</filter-name> <filter-class>onlyfun.caterpillar.FilterDemo2</filter-class> </filter>
<filter-mapping> <filter-name>FilterDemo2</filter-name> <url-pattern>/*</url-pattern> </filter-mapping> ...
則請求Web應用程式下的任一個資源,都會先執行FilterDemo1,然後再執行FilterDemo2,最後呼叫請求的資源,如果請求的資源是 JSP網頁,而它的功能只是印出 5 個Hello! World!:
<% for(int i = 0; i < 5; i++) out.println("Hello! World!"); %>
則呼叫該JSP網頁時,所得到的結果是:
Filter 1 is doing!!!
Filter 2 is doing!!!
Hello! World!
Hello! World!
Hello! World!
Hello! World!
Hello! World!
Filter 2's work is done
Filter 1's work is done
|