Web客戶端訪問服務器的時候通過Tomcat訪問servlet,Filter作爲過濾器,其實就是在Tomcat和servlet之間建立了一道關卡,對客戶端請求和服務端響應進行攔截處理。
二.Filter的實現1:創建一個類實現javax.servlet.Filter接口,並實現其的init()、doFilter()、destroy()方法。
init():初始化方法,可以獲取filter配置文件中的數據,在Tomcat啓動的時候就執行doFilter():Filter的核心,這行希望過濾器完成的功能。
Destroy():Filter銷燬的時候調用。
將要過濾的任務放在這個方法中,有三個參數
ServletRequest, ServletResponse,傳遞請求和響應的參數
FilterChain:執行doFilter方法將請求和響應傳遞給下一個Filter或者JSP/Servlet繼續執行。
3.web.xml中配置filter,執行過濾的頁面。
4.執行過程:
編寫好Filter,並配置對哪個web資源進行攔截後,WEB服務器每次在調用web資源的service方法之前,都會先調用一下filter的doFilter方法,傳遞一個filterChain對象進來,filterChain對象是filter接口中最重要的一個對 象,它也提供了一個doFilter方法,開發人員可以根據需求決定是否調用此方法,調用該方法,則web服務器就會調用web資源的service方 法,即web資源就會被訪問,否則web資源不會被訪問。
圖:Filter在整個執行過程中的位置。
三.Filter開發實例
處理字符編碼的Filter:在DRP項目中添加,修改用戶信息,jsp頁面中來設置請求和響應的字符集,不會出現亂碼情況。
<span style="font-size:14px;"><%@ page language="java" contentType="text/html; charset=GB18030"
pageEncoding="GB18030"%>
request.setCharacterEncoding("GB18030");</span>
1.編寫java類實現Filter接口,並實現其doFilter方法
package com.bjpowernode.drp.util.filter;
import java.io.IOException;
import javax.servlet.Filter;
import javax.servlet.FilterChain;
import javax.servlet.FilterConfig;
mport javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
public class CharseEncodingFilter implements Filter {
//成員變量,存放讀取filter配置文件中的信息
private String endcoding;
//銷燬方法
public void destroy() {}
//filter核心方法
public void doFilter(ServletRequest request, ServletResponse response,
FilterChain chain) throws IOException, ServletException {
//設置字符集
//第一種方式直接填寫字符編碼的格式,這樣不容易修改
request.setCharacterEncoding("GB18030");
response.setCharacterEncoding("GB18030");
//第二種方式讀取filter配置文件中的信息這樣便於維護和修改字符編碼格式
request.setCharacterEncoding(endcoding);
response.setCharacterEncoding(endcoding);
//繼續執行
chain.doFilter(request, response);
}
//filter初始化
public void init(FilterConfig arg0) throws ServletException {
this.endcoding =arg0.getInitParameter("encoding"); //讀取filter配置文件中的信息
}
}
FilterConfig接口:用戶在配置filter時,可以使用<init-param>爲filter配置一些初始化參數,當web容器實例化Filter對象,調用其init方法時,會把封裝了filter初始化參數的filterConfig對象傳遞進來。在編寫filter時,通過filterConfig對象的方法,就可獲得
String getFilterName():得到filter的名稱。
String getInitParameter(String name): 返回在部署描述中指定名稱的初始化參數的值。如果不存在返回null.
Enumeration getInitParameterNames():返回過濾器的所有初始化參數的名字的枚舉集合。
public ServletContext getServletContext():返回Servlet上下文對象的引用。
2.配置web.xml
<filter>
<filter-name>CharseEncodingFilter</filter-name> <!--別名-->
<filter-class>com.bjpowernode.drp.util.filter.CharseEncodingFilter</filter-class> <!--執行操作的類-->
<init-param> <!--參數-->
<param-name>encoding</param-name> <!--參數名-->
<param-value>GBK</param-value> <!--參數值-->
</init-param>
</filter>
<filter-mapping> <!--定義需要過濾的資源-->
<filter-name>CharseEncodingFilter</filter-name> <!--別名與上面的相同-->
<url-pattern>/sysmgr/user_modify.jsp</url-pattern> <!--具體的頁面-->
</filter-mapping>
Filter鏈:在一個web應用中,可以開發編寫多個Filter,這些Filter組合起來稱之爲一個Filter鏈。
web服務器根據Filter在web.xml文件中的註冊順序,決定先調用哪個Filter,當第一個Filter的doFilter方法被調用時,web服務器會創建一個代表Filter鏈的FilterChain對象傳遞給該方法。在doFilter方法中,開發人員如果調用了FilterChain對象的doFilter方法,則web服務器會檢查FilterChain對象中是否還有filter,如果有,則調用第2個filter,如果沒有,則調用目標資源。一個對象可以配置多個filter,同時一個filter也可以對多個對象起作用。
四:總結
filter的思想是面向切面編程,他提供了一種聲明式服務,聲明式服務非常強大,具有可拔插的能力,同時filter只是對post提交其作用。