和Servlet一樣,F(xiàn)ilter的創(chuàng)建和銷(xiāo)毀也是由WEB服務(wù)器負(fù)責(zé)。
1、在應(yīng)用啟動(dòng)的時(shí)候就進(jìn)行裝載Filter類而servlet是在請(qǐng)求時(shí)才創(chuàng)建(但filter與Servlet的load-on-startup配置效果相同)。
2、容器創(chuàng)建好Filter對(duì)象實(shí)例后,調(diào)用init()方法。接著被Web容器保存進(jìn)應(yīng)用級(jí)的集合容器中去了等待著,用戶訪問(wèn)資源。
3、當(dāng)用戶訪問(wèn)的資源正好被Filter的url-pattern攔截時(shí),容器會(huì)取出Filter類調(diào)用doFilter方法,下次或多次訪問(wèn)被攔截的資源時(shí),Web容器會(huì)直接取出指定Filter對(duì)象實(shí)例調(diào)用doFilter方法(Filter對(duì)象常駐留Web容器了)。
4、當(dāng)應(yīng)用服務(wù)被停止或重新裝載了,則會(huì)執(zhí)行Filter的destroy方法,F(xiàn)ilter對(duì)象銷(xiāo)毀。
當(dāng)客戶端發(fā)出Web資源的請(qǐng)求時(shí),Web服務(wù)器根據(jù)應(yīng)用程序配置文件設(shè)置的過(guò)濾規(guī)則進(jìn)行檢查,若客戶請(qǐng)求滿足過(guò)濾規(guī)則,則對(duì)客戶請(qǐng)求/響應(yīng)進(jìn)行攔截,對(duì)請(qǐng)求頭和請(qǐng)求數(shù)據(jù)進(jìn)行檢查或改動(dòng),并依次通過(guò)過(guò)濾器鏈,最后把請(qǐng)求/響應(yīng)交給請(qǐng)求的Web資源處理。
請(qǐng)求信息在過(guò)濾器鏈中可以被修改,也可以根據(jù)條件讓請(qǐng)求不發(fā)往資源處理器,并直接向客戶機(jī)發(fā)回一個(gè)響應(yīng)。當(dāng)資源處理器完成了對(duì)資源的處理后,響應(yīng)信息將逐級(jí)逆向返回。同樣在這個(gè)過(guò)程中,用戶可以修改響應(yīng)信息,從而完成一定的任務(wù)。
過(guò)濾鏈的好處是,執(zhí)行過(guò)程中任何時(shí)候都可以打斷,只要不執(zhí)行chain.doFilter()就不會(huì)再執(zhí)行后面的過(guò)濾器和請(qǐng)求的內(nèi)容。

針對(duì)多個(gè)過(guò)濾器來(lái)說(shuō),例如,EncodingFilter負(fù)責(zé)設(shè)置編碼,SecurityFilter負(fù)責(zé)控制權(quán)限,服務(wù)器會(huì)按照web.xml中過(guò)濾器定義的先后循序組裝成一條鏈,然后一次執(zhí)行其中的doFilter()方法,在實(shí)際使用時(shí),就要特別注意過(guò)濾鏈的執(zhí)行順序問(wèn)題,像EncodingFilter就一定要放在所有Filter之前,這樣才能確保在使用請(qǐng)求中的數(shù)據(jù)前設(shè)置正確的編碼。
Filter接口有三個(gè)方法,并且這個(gè)三個(gè)都是與Filter的生命相關(guān)的方法
init(Filterconfig):代表filter對(duì)象初始化方法 filter對(duì)象創(chuàng)建時(shí)執(zhí)行
doFilter(ServletRequest,ServletResponse,FilterChain):代表filter執(zhí)行過(guò)濾的核心方法,如果某資源在已經(jīng)被配置到這個(gè)filter進(jìn)行過(guò)濾的話,那么每次訪問(wèn)這個(gè)資源都會(huì)執(zhí)行doFilter方法
destory():代表是filter銷(xiāo)毀方法 當(dāng)filter對(duì)象銷(xiāo)毀時(shí)執(zhí)行該方法
Filter對(duì)象的生命周期:
Filter何時(shí)創(chuàng)建:服務(wù)器啟動(dòng)時(shí)就創(chuàng)建該filter對(duì)象
Filter何時(shí)銷(xiāo)毀:服務(wù)器關(guān)閉時(shí)filter銷(xiāo)毀
● init(FilterConfig)
其中參數(shù)config代表 該Filter對(duì)象的配置信息的對(duì)象,內(nèi)部封裝是該filter的配置信息。
@Override
//初始化方法:Filter創(chuàng)建時(shí)去執(zhí)行init方法
public void init(FilterConfig filterConfig) throws ServletException {
//1、獲得web.xml中filter 的名稱 QuickFilter1
System.out.println(filterConfig.getFilterName());
//2、還能獲得當(dāng)前filter的一些初始化參數(shù)
System.out.println(filterConfig.getInitParameter("aaa"));
//3、獲得servletContext
filterConfig.getServletContext();
System.out.println("init....");
}
● destory()方法
filter對(duì)象銷(xiāo)毀時(shí)執(zhí)行
● doFilter方法
doFilter(ServletRequest,ServletResponse,FilterChain)
其中的參數(shù):
ServletRequest/ServletResponse:每次在執(zhí)行doFilter方法時(shí) web容器負(fù)責(zé)創(chuàng)建一個(gè)request和一個(gè)response對(duì)象作為doFilter的參數(shù)傳遞進(jìn)來(lái)。該request個(gè)該response就是在訪問(wèn)目標(biāo)資源的service方法時(shí)的request和response。
FilterChain:過(guò)濾器鏈對(duì)象,通過(guò)該對(duì)象的doFilter方法可以放行該請(qǐng)求

<filter>
? ?? ??<filter-nameFilter1</filter-name>
? ?? ??<filter-class>com.filter.Filter1</filter-class>
</filter>
<filter-mapping>
? ?? ??<filter-name>Filter1</filter-name>
? ?? ??<url-pattern>/*</url-pattern>
</filter-mapping>
4、url-pattern配置時(shí)
● 完全匹配 /sertvle1
● 目錄匹配 /aaa/bbb/* ----最多的
/user/*:訪問(wèn)前臺(tái)的資源進(jìn)入此過(guò)濾器
/admin/*:訪問(wèn)后臺(tái)的資源時(shí)執(zhí)行此過(guò)濾器
● 擴(kuò)展名匹配 *.abc *.jsp
注意:url-pattern可以使用servlet-name替代,也可以混用
配置格式為:*
REQUEST:默認(rèn)值,代表直接訪問(wèn)某個(gè)資源時(shí)執(zhí)行filter
FORWARD:轉(zhuǎn)發(fā)時(shí)才執(zhí)行filter
INCLUDE: 包含資源時(shí)執(zhí)行filter
ERROR:發(fā)生錯(cuò)誤時(shí) 進(jìn)行跳轉(zhuǎn)是執(zhí)行filter
● 公共代碼的提取
● 可以對(duì)request和response中的方法進(jìn)行增強(qiáng)(裝飾者模式/動(dòng)態(tài)代理)
● 進(jìn)行權(quán)限控制