Filter過濾器
簡介
filter可以認(rèn)為是servlet的一種加強(qiáng)版,主要用于對用戶請求request進(jìn)行預(yù)處理,也可以對response進(jìn)行后處理,是個典型的處理鏈。使用filter的完整流程是,filter對用戶請求進(jìn)行預(yù)處理,接著將請求HttpServletRequest交給Servlet處理并生成響應(yīng)。最后Filter再對服務(wù)器響應(yīng)HttpServletResponse進(jìn)行后處理。Servlet與Servlet具有完全相同的生命周期,而Filter也可以通過<<init-para>init-para>進(jìn)行初始化參數(shù)的配置,并通過FilterConfig傳送給filter
創(chuàng)建Filter過濾器的兩步
創(chuàng)建一個Filter只需兩步
- 創(chuàng)建Filter處理類,即實(shí)現(xiàn)javax.servlet.Filter接口
- web.xml文件中配置filter
javax.servlet.Filter接口介紹
Filter必須實(shí)現(xiàn)javax.servlet.Filter接口,在該接口中定義了三個方法
-
void init(FilterConfig config):用于Filter的初始化,F(xiàn)ilterConfig用于訪問Filter的配置信息 -
void destroy():用于Filter銷毀前,某些資源的釋放回收
*void doFilter(ServletRequest request,ServletResponse response,F(xiàn)ilterChain chain):實(shí)現(xiàn)過濾功能的核心方法,該方法是對每個請求及響應(yīng)增加額外的處理,該方法實(shí)現(xiàn)對用戶請求request進(jìn)行預(yù)處理,也可以實(shí)現(xiàn)對服務(wù)器響應(yīng)response進(jìn)行后處理---它們的分界線為是否調(diào)用了chain.doFilter(request,response),執(zhí)行該方法之前,即對用戶請求request進(jìn)行預(yù)處理,執(zhí)行該方法之后,即對服務(wù)器響應(yīng)response進(jìn)行后處理。
web.xml配置介紹
<filter-name>用于為過濾器指定一個名字,該元素的內(nèi)容不能為空。
<filter-class>元素用于指定過濾器的完整的限定類名。
<init-param>元素用于為過濾器指定初始化參數(shù),它的子元素<param-name>指定參數(shù)的名字,<param-value>指定參數(shù)的值。
在過濾器中,可以使用FilterConfig接口對象來訪問初始化參數(shù)。
<filter-mapping>元素用于設(shè)置一個 Filter 所負(fù)責(zé)攔截的資源。一個Filter攔截的資源可通過兩種方式來指定:Servlet 名稱和資源訪問的請求路徑
<filter-name>子元素用于設(shè)置filter的注冊名稱。該值必須是在<filter>元素中聲明過的過濾器的名字
<url-pattern>設(shè)置 filter 所攔截的請求路徑(過濾器關(guān)聯(lián)的URL樣式)
<servlet-name>指定過濾器所攔截的Servlet名稱。
<dispatcher>指定過濾器所攔截的資源被 Servlet 容器調(diào)用的方式,可以是REQUEST,INCLUDE,FORWARD和ERROR之一,默認(rèn)REQUEST。用戶可以設(shè)置多個<dispatcher> 子元素用來指定 Filter 對資源的多種調(diào)用方式進(jìn)行攔截。
<dispatcher> 子元素可以設(shè)置的值及其意義:
REQUEST:當(dāng)用戶直接訪問頁面時,Web容器將會調(diào)用過濾器。如果目標(biāo)資源是通過RequestDispatcher的include()或forward()方法訪問時,那么該過濾器就不會被調(diào)用。
INCLUDE:如果目標(biāo)資源是通過RequestDispatcher的include()方法訪問時,那么該過濾器將被調(diào)用。除此之外,該過濾器不會被調(diào)用。
FORWARD:如果目標(biāo)資源是通過RequestDispatcher的forward()方法訪問時,那么該過濾器將被調(diào)用,除此之外,該過濾器不會被調(diào)用。
ERROR:如果目標(biāo)資源是通過聲明式異常處理機(jī)制調(diào)用時,那么該過濾器將被調(diào)用。除此之外,過濾器不會被調(diào)用。
Filters使用案例
Example1:自己對相應(yīng)業(yè)務(wù)寫一個實(shí)現(xiàn)Filter接口的類
<!-- 請求url日志記錄過濾器 -->
<filter>
<filter-name>logfilter</filter-name>
<filter-class>com.weijia.filterservlet.LogFilter</filter-class>
</filter>
<filter-mapping>
<filter-name>logfilter</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
package com.weijia.filterservlet;
import java.io.IOException;
import java.util.Enumeration;
import java.util.HashMap;
import javax.servlet.Filter;
import javax.servlet.FilterChain;
import javax.servlet.FilterConfig;
import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
public class EncodingFilter implements Filter {
private String encoding;
private HashMap<String,String> params = new HashMap<String,String>();
// 項(xiàng)目結(jié)束時就已經(jīng)進(jìn)行銷毀
public void destroy() {
System.out.println("end do the encoding filter!");
params=null;
encoding=null;
}
public void doFilter(ServletRequest req, ServletResponse resp,FilterChain chain) throws IOException, ServletException {
System.out.println("before encoding " + encoding + " filter!");
req.setCharacterEncoding(encoding);
chain.doFilter(req, resp);
System.out.println("after encoding " + encoding + " filter!");
System.err.println("----------------------------------------");
}
// 項(xiàng)目啟動時就已經(jīng)進(jìn)行讀取
public void init(FilterConfig config) throws ServletException {
System.out.println("begin do the encoding filter!");
encoding = config.getInitParameter("encoding");
for (Enumeration<?> e = config.getInitParameterNames(); e.hasMoreElements();) {
String name = (String) e.nextElement();
String value = config.getInitParameter(name);
params.put(name, value);
}
}
}
Example2:防止中文亂碼過濾器
<filter>
<filter-name>encoding</filter-name>
<filter-class>org.springframework.web.filter.CharacterEncodingFilter</filter-class>
<init-param>
<param-name>encoding</param-name><!--用來指定一個具體的字符集-->
<param-value>UTF-8</param-value>
</init-param>
<init-param>
<param-name>forceEncoding</param-name><!--true:無論request是否指定了字符集,都是用encoding;false:如果request已指定一個字符集,則不使用encoding-->
<param-value>false</param-value>
</init-param>
</filter>
<filter-mapping>
<filter-name>encoding</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
參考文章&&推薦閱讀
Filter過濾器
JavaWeb學(xué)習(xí)篇之----Servlet過濾器Filter和監(jiān)聽器