ServletAPI中提供了一個(gè)Filter接口,開發(fā)web應(yīng)用時(shí),如果編寫的Java類實(shí)現(xiàn)了這個(gè)接口,則把這個(gè)java類稱之為過濾器Filter。
通過Filter技術(shù),開發(fā)人員可以實(shí)現(xiàn)用戶在訪問某個(gè)目標(biāo)資源之前,對(duì)訪問的請(qǐng)求和響應(yīng)進(jìn)行攔截。簡單說,就是可以實(shí)現(xiàn)web容器對(duì)某資源的訪問前截獲進(jìn)行相關(guān)的處理,還可以在某資源向web容器返回響應(yīng)前進(jìn)行截獲進(jìn)行處理。
下圖是filter調(diào)用關(guān)系的UML圖:

一個(gè)filter必須實(shí)現(xiàn)javax.servlet.Filter。
三個(gè)方法
1. voidsetFilterConfig(FilterConfig config) //設(shè)置filter 的配置對(duì)象;
2. FilterConfiggetFilterConfig() //返回filter的配置對(duì)象;
3. voiddoFilter(ServletRequest req,ServletResponse res,FilterChain chain) //執(zhí)行filter的工作
在HttpServletRequest到達(dá)Servlet之前,攔截客戶的HttpServletRequest。
根據(jù)需要檢查HttpServletRequest,也可以修改HttpServletRequest頭和數(shù)據(jù)。
在HttpServletResponse到達(dá)客戶端之前,攔截HttpServletResponse。
根據(jù)需要檢查HttpServletResponse,也可以修改HttpServletResponse頭和數(shù)據(jù)。
用戶授權(quán)的Filter:Filter負(fù)責(zé)檢查用戶請(qǐng)求,根據(jù)請(qǐng)求過濾用戶非法請(qǐng)求。
日志Filter:詳細(xì)記錄某些特殊的用戶請(qǐng)求。
負(fù)責(zé)解碼的Filter:包括對(duì)非標(biāo)準(zhǔn)編碼的請(qǐng)求解碼。
Filter可攔截多個(gè)請(qǐng)求或響應(yīng);一個(gè)請(qǐng)求或響應(yīng)也可被多個(gè)請(qǐng)求攔截。
創(chuàng)建一個(gè)Filter只需要兩個(gè)步驟:1.創(chuàng)建Filter處理類(如:MyFiletr)實(shí)現(xiàn)javax.servlet.Filter接口;2.web.xml中配置Filter
1、簡單的記錄日志的Filter,這個(gè)Filter負(fù)責(zé)攔截所符合條件的用戶請(qǐng)求,并將請(qǐng)求的信息記錄在日志中。


web.xml配置信息:

總結(jié):上面的程序?qū)崿F(xiàn)了doFilter()方法,實(shí)現(xiàn)該方法就可以實(shí)現(xiàn)對(duì)用戶請(qǐng)求進(jìn)行預(yù)處理,也可以實(shí)現(xiàn)對(duì)服務(wù)器響應(yīng)進(jìn)行后處理--他們的分界線為是否調(diào)用了chain.doFilter(),執(zhí)行該方法之前,即對(duì)用戶請(qǐng)求進(jìn)行預(yù)處理;執(zhí)行該方法之后,即對(duì)服務(wù)器響應(yīng)進(jìn)行后處理。
在上面的請(qǐng)求Filter中,僅在日志中記錄請(qǐng)求的URL,對(duì)所有的請(qǐng)求都執(zhí)行chain.doFilter (request,reponse)方法,當(dāng)Filter對(duì)請(qǐng)求過濾后,依然將請(qǐng)求發(fā)送到目的地址。如果需要檢查權(quán)限,可以在Filter中根據(jù)用戶請(qǐng)求的HttpSession,判斷用戶權(quán)限是否足夠。如果權(quán)限不夠,直接調(diào)用重定向即可,無須調(diào)用chain.doFilter(request,reponse)方法。
2、簡單的認(rèn)證登錄Filter。


web.xml配置信息:

3、再次闡述Filter及一個(gè)應(yīng)用小例子。
Filter也稱之為過濾器,它是Servlet技術(shù)中比較激動(dòng)人心的技術(shù),WEB開發(fā)人員通過Filter技術(shù),對(duì)web服務(wù)器管理的所有web資源:例如Jsp, Servlet, 靜態(tài)圖片文件或靜態(tài) html 文件等進(jìn)行攔截,從而實(shí)現(xiàn)一些特殊的功能。例如實(shí)現(xiàn)URL級(jí)別的權(quán)限訪問控制、過濾敏感詞匯、壓縮響應(yīng)信息等一些高級(jí)功能。
Servlet API中提供了一個(gè)Filter接口,開發(fā)web應(yīng)用時(shí),如果編寫的Java類實(shí)現(xiàn)了這個(gè)接口,則把這個(gè)Java類稱之為過濾器Filter。通過Filter技術(shù),開發(fā)人員可以實(shí)現(xiàn)用戶在訪問某個(gè)目標(biāo)資源之前,對(duì)訪問的請(qǐng)求和響應(yīng)進(jìn)行攔截。簡單說,就是可以實(shí)現(xiàn)web容器對(duì)某資源的訪問前截獲進(jìn)行相關(guān)的處理,還可以在某資源向web容器返回響應(yīng)前進(jìn)行截獲處理。

web.xml配置信息:

Filter接口中有一個(gè)doFilter方法,當(dāng)開發(fā)人員編寫好Filter類實(shí)現(xiàn)doFilter方法,并配置對(duì)哪個(gè)web資源進(jìn)行攔截后,WEB服務(wù)器每次在調(diào)用web資源的service方法之前(服務(wù)器內(nèi)部對(duì)資源的訪問機(jī)制決定的),都會(huì)先調(diào)用一下filter的doFilter方法。
Filter的生命周期和Servlet一樣,F(xiàn)ilter的創(chuàng)建和銷毀也是由WEB服務(wù)器負(fù)責(zé)。不過與Servlet區(qū)別的是,它是1>在應(yīng)用啟動(dòng)的時(shí)候就進(jìn)行裝載Filter類(與Servlet的load-on-startup配置效果相同)。2>容器創(chuàng)建好Filter對(duì)象實(shí)例后,調(diào)用init()方法。接著被Web容器保存進(jìn)應(yīng)用級(jí)的集合容器中去了等待著,用戶訪問資源。3>當(dāng)用戶訪問的資源正好被Filter的url-pattern攔截時(shí),容器會(huì)取出Filter類調(diào)用doFilter方法,下次或多次訪問被攔截的資源時(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ì)象銷毀。注意:init方法與destroy方法只會(huì)直接一次。
Filter不僅可以通過url-pattern來指定攔截哪些url匹配的資源。而且還可以通過servlet-name來指定攔截哪個(gè)指定的servlet(專門為某個(gè)servlet服務(wù)了,servlet-name對(duì)應(yīng)Servlet的相關(guān)配置)。