Filter可認爲是Servlet的「增強版」,主要用於對用戶請求進行預處理,也能夠對HttpServletResponse進行後處理,是個典型的處理鏈。Filter也能夠對用戶請求生成相應,這一點與Servlet相同,但實際上不多會這樣使用。使用Filter的完整流程是:Filter對用戶的請求進行預處理,接着將請求交給Servlet進行處理並響應生成,最後Filter在對服務器響應進行後處理。java
1. Filter有以下幾個用處:web
在HttpServletRequest到達Servlet以前,攔截客戶的HttpServletRequest服務器
根據須要,檢查HttpServletRequest,也能夠修改HttpServletRequest的頭和數據app
在HttpServletResponse到達客戶端以前,攔截HttpServletResponse異步
根據須要,檢查HttpServletResponse,也能夠修改HttpServletResponse的頭和數據jsp
2. Filter有以下幾個種類:async
用戶受權的Filter:Filter負責檢查用戶請求,根據請求過濾用戶的非法請求,一般用於權限管理。this
日誌Filter:詳細記錄某些特殊的用戶請求編碼
負責解碼的Filter:包括對非標準編碼的請求解碼url
能改變XML內容的XSLT Filter等
3. 建立一個Filter只需兩個步驟:
1). 建立Filter處理類 2). 在web.xml文件中配置Filter
3.1 建立Filter處理類
建立Filter必須實現javax.servlet.Filter接口,在該接口中定義了以下三個方法:
void init(FilterConfig config):用於完成Filter的初始化
void destroy():用於Filter銷燬錢,完成某些資源的回收
void doFilter(ServletRequest request, ServletResponse response, FilterChain chain):實現過濾功能,該方法就是對每一個請求及響應增長的額外處理
下面是一個日誌Filter,它負責攔截全部的用戶請求,並將請求的信息記錄在日誌中。
@WebFilter(filterName="log", urlPatterns={"/*"}, initParams={ //這裏使用註解的方式配置Filter @WebInitParam(name="encoding" value="UTF-8"), @WebInitParam(name="loginPage" value="/login.jsp") }) public class LogFilter implements Filter { private FilterConfig config;//FilterConfig可用於訪問Filter的配置信息 public void init(FilterConfig config) { this.config = config; } public void destroy(){this.config = null;} public void doFilter(ServletRequest req, ServletResponse resp, FilterChain chain) throws IOException, ServletException{ //下面的代碼用於對用戶請求執行預處理 ServletContext context = this.config.getServletContext();//獲取ServletContext對象,用於記錄日誌 long before = System.currentTimeMillis(); System.out.println("開始過濾..."); HttpServletRequest request = (HttpServletRequest)req; System.out.println("已經攔截到用戶的請求地址:" + request.getServletPath()); chain.doFilter(req, resp);//Filter只是鏈式處理,請求依然放行到目的地址 //下面的代碼用於對服務器響應執行後處理 long after = System.currentTimeMillis(); System.out.println("過濾結束"); System.out.println("請求被定位到:" + request.getRequestURI() + " 耗時:" + (after - before));//這裏只是輸出提示信息 } }
上面的代碼實現了doFilter()方法,實現該方法能夠實現對用戶請求的預處理,也可實現對服務器響應的後處理,它們的分界線爲是否調用了chain.doFilter()方法,在這以前的是對用戶請求的預處理,在這以後的,是對服務器響應的後處理。當Filter對請求過濾後,依然將請求發送到目的地址。若是須要檢查權限,能夠在Filter中根據用戶請求的HttpSession,判斷用戶權限是否足夠。若是權限不足,直接調用重定向便可,無需調用chain.doFilter()方法。
3.2 配置Filter
Filter在web.xml中的配置和Servlet在web.xml中的配置很類似,區別在於:一個Servlet一般只配置一個URL,而Filter能夠同時攔截多個請求的URL,所以在配置Filter的urlPatterns時,一般會使用模式字符串,使得Filter能夠攔截多個請求。和Servlet類似的是,配置Filter一樣有兩種方式:1). 在Filter類中經過註解進行配置 2). 在web.xml文件中進行配置
@WebFilter支持的經常使用屬性介紹:
asyncSupported:指定該Filter是否支持異步操做模式
dispatcherTypes:指定該Filter僅對那種dispatcher模式的請求進行過濾。該屬性支持ASYNC, ERROR, FORWARD, INCLUDE, REQUEST這5個值的任意組合,默認值爲同時過濾這5中模式的請求
displayName:指定該Filter的顯示名
filterName:指定該Filter的名稱
initParams:用於爲該Filter配置參數
servletNames:該屬性能夠指定多個Servlet名稱,用於指定該Filter僅對這些Servlet進行過濾
urlPatterns/value:這兩個屬性的做用徹底相同,用於指定該Filter所攔截的URL
下面是一個在web.xml中配置Filter的例子:
<filter> <filter-name>log</filter-name> <!-- 此屬性至關於@WebFilter中的filterName屬性 --> <filter-class>com.abc.LogFilter</filter-class> <!-- Filter的實現類 --> <init-param> <param-name>encoding</param-name> <param-value>UTF-8</param-value> </init-param> <init-param> <param-name>loginPage</param-name> <param-value>/login.jsp</param-value> </init-param> </filter> <filter-mapping> <filter-name>log</filter-name> <url-pattern>/*</url-pattern> <!-- 負責攔截全部的URL,至關於@WebFilter中的urlPatterns屬性 --> </filter-mapping>