17.6Filter過濾器

一、Filter簡介

Filter也稱之為過濾器,它是Servlet技術(shù)中最激動人心的技術(shù),WEB開發(fā)人員通過Filter技術(shù),對web服務(wù)器管理的所有web資源:例如Jsp, Servlet, 靜態(tài)圖片文件或靜態(tài) html 文件等進行攔截,從而實現(xiàn)一些特殊的功能。例如實現(xiàn)URL級別的權(quán)限訪問控制、過濾敏感詞匯、壓縮響應(yīng)信息等一些高級功能。

Servlet API中提供了一個Filter接口,開發(fā)web應(yīng)用時,如果編寫的Java類實現(xiàn)了這個接口,則把這個java類稱之為過濾器Filter。通過 Filter技術(shù),開發(fā)人員可以實現(xiàn)用戶在訪問某個目標(biāo)資源之前,對訪問的請求和響應(yīng)進行攔截,如下所示:

Filter請求處理

在攔截器出來之前,F(xiàn)ilter是web開發(fā)的基礎(chǔ)核心,可以負(fù)責(zé)權(quán)限控制、日志記錄、字符集處理等等

二、Filter是如何實現(xiàn)攔截的?

Filter接口中有一個doFilter方法,當(dāng)我們編寫好Filter,并配置對哪個web資源進行攔截后,WEB服務(wù)器每次在調(diào)用web 資源的service方法之前,都會先調(diào)用一下filter的doFilter方法,因此,在該方法內(nèi)編寫代碼可達(dá)到如下目的:

調(diào)用目標(biāo)資源之前,讓一段代碼執(zhí)行。
1、是否調(diào)用目標(biāo)資源(即是否讓用戶訪問web資源)。
2、調(diào)用目標(biāo)資源之后,讓一段代碼執(zhí)行。
web服務(wù)器在調(diào)用doFilter方法時,會傳遞一個filterChain對象進來,filterChain對象是filter接口中最重 要的一個對象,它也提供了一個doFilter方法,開發(fā)人員可以根據(jù)需求決定是否調(diào)用此方法,調(diào)用該方法,則web服務(wù)器就會調(diào)用web資源的service方法,即web資源就會被訪問,否則web資源不會被訪問。

三、Filter開發(fā)入門

3.1、Filter開發(fā)步驟

Filter開發(fā)分為二個步驟:
1、編寫java類實現(xiàn)Filter接口,并實現(xiàn)其doFilter方法。
2、在 web.xml 文件中使用<filter>和<filter-mapping>元素對編寫的filter類進行注冊,并設(shè)置它所能攔截的資源。

下面以字符集處理的過濾器進行舉例。
在java開發(fā)中,經(jīng)常會遇到中文亂碼的問題,原因就是頁面提交的中文是ISO88590-1格式的,到后臺如果不進行轉(zhuǎn)碼,就會出現(xiàn)中文亂碼。但是不能每個請求都要手動轉(zhuǎn)碼吧,所以采用filter就可以輕松解決這個問題了。

public class CharacterEncodingFilter implements Filter {
    private FilterConfig filterConfig = null;
    //設(shè)置默認(rèn)的字符編碼
    private String defaultCharset = "UTF-8";

    public void doFilter(ServletRequest req, ServletResponse resp,
                         FilterChain chain) throws IOException, ServletException {

        HttpServletRequest request = (HttpServletRequest) req;
        HttpServletResponse response = (HttpServletResponse) resp;
        String charset = filterConfig.getInitParameter("charset");
        if (charset == null) {
            charset = defaultCharset;
        }
        request.setCharacterEncoding(charset);
        response.setCharacterEncoding(charset);
        response.setContentType("text/html;charset=" + charset);
        chain.doFilter(request, response);
    }

    public void init(FilterConfig filterConfig) throws ServletException {
        //得到過濾器的初始化配置信息
        this.filterConfig = filterConfig;
    }

    public void destroy() {

    }
}

原理就是在每個請求時,設(shè)置request和response的字符集都是UTF-8

3.2、Filter鏈

在一個web應(yīng)用中,可以開發(fā)編寫多個Filter,這些Filter組合起來稱之為一個Filter鏈。

web服務(wù)器根據(jù) Filter在web.xml文件中的注冊順序,決定先調(diào)用哪個Filter,當(dāng)?shù)谝粋€Filter的doFilter方法被調(diào)用時,web服務(wù)器會創(chuàng)建 一個代表Filter鏈的FilterChain對象傳遞給該方法。在doFilter方法中,開發(fā)人員如果調(diào)用了FilterChain對象的 doFilter方法,則web服務(wù)器會檢查FilterChain對象中是否還有filter,如果有,則調(diào)用第2個filter,如果沒有,則調(diào)用目 標(biāo)資源。

四、Filter的生命周期

4.1、Filter的創(chuàng)建

Filter的創(chuàng)建和銷毀由WEB服務(wù)器負(fù)責(zé)。 web 應(yīng)用程序啟動時,web 服務(wù)器將創(chuàng)建Filter 的實例對象,并調(diào)用其init方法,完成對象的初始化功能,從而為后續(xù)的用戶請求作好攔截的準(zhǔn)備工作,filter對象只會創(chuàng)建一次,init方法也只會執(zhí)行一次。通過init方法的參數(shù),可獲得代表當(dāng)前filter配置信息的FilterConfig對象。

4.2、Filter的銷毀

Web容器調(diào)用destroy方法銷毀Filter。destroy方法在Filter的生命周期中僅執(zhí)行一次。在destroy方法中,可以釋放過濾器使用的資源。

4.3、FilterConfig接口

用戶在配置filter時,可以使用<init-param>為filter配置一些初始化參數(shù),當(dāng)web容器實例化Filter 對象,調(diào)用其init方法時,會把封裝了filter初始化參數(shù)的filterConfig對象傳遞進來。因此開發(fā)人員在編寫filter時,通過 filterConfig對象的方法,就可獲得:

  • 1、String getFilterName():得到filter的名稱。
  • 2、String getInitParameter(String name): 返回在部署描述中指定名稱的初始化參數(shù)的值。如果不存在返回null.
  • 3、Enumeration getInitParameterNames():返回過濾器的所有初始化參數(shù)的名字的枚舉集合。
  • 4、public ServletContext getServletContext():返回Servlet上下文對象的引用。

五、Filter的部署

Filter的部署分為兩個步驟:

  • 1、注冊Filter
  • 2、映射Filter

5.1、注冊Filter

開發(fā)好Filter之后,需要在web.xml文件中進行注冊,這樣才能夠被web服務(wù)器調(diào)用

在web.xml文件中注冊Filter范例:

 <filter>
        <filter-name>CharacterEncodingFilter</filter-name>
        <filter-class>com.critc.filter.CharacterEncodingFilter</filter-class>
        <init-param>
            <param-name>charset</param-name>
            <param-value>UTF-8</param-value>
        </init-param>
    </filter>

5.2、映射Filter

在web.xml文件中注冊了Filter之后,還要在web.xml文件中映射Filter

<!--映射過濾器-->
   <filter-mapping>
        <filter-name>CharacterEncodingFilter</filter-name>
        <url-pattern>/*</url-pattern>
    </filter-mapping>
  • 1、<filter-mapping>元素用于設(shè)置一個 Filter 所負(fù)責(zé)攔截的資源。一個Filter攔截的資源可通過兩種方式來指定:Servlet 名稱和資源訪問的請求路徑
  • 2、<filter-name>子元素用于設(shè)置filter的注冊名稱。該值必須是在<filter>元素中聲明過的過濾器的名字
  • 3、<url-pattern>設(shè)置 filter 所攔截的請求路徑(過濾器關(guān)聯(lián)的URL樣式)

現(xiàn)在有了SpringMVC的攔截器和Struts的攔截器,F(xiàn)ilter用的越來越少,不過原理還是要掌握的,便于讀懂歷史項目。

源碼下載

本例子詳細(xì)源碼

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌,老刑警劉巖,帶你破解...
    沈念sama閱讀 230,431評論 6 544
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異,居然都是意外死亡,警方通過查閱死者的電腦和手機,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 99,637評論 3 429
  • 文/潘曉璐 我一進店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人,你說我怎么就攤上這事。” “怎么了?”我有些...
    開封第一講書人閱讀 178,555評論 0 383
  • 文/不壞的土叔 我叫張陵,是天一觀的道長。 經(jīng)常有香客問我,道長,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 63,900評論 1 318
  • 正文 為了忘掉前任,我火速辦了婚禮,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘。我一直安慰自己,他們只是感情好,可當(dāng)我...
    茶點故事閱讀 72,629評論 6 412
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著,像睡著了一般。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 55,976評論 1 328
  • 那天,我揣著相機與錄音,去河邊找鬼。 笑死,一個胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播,決...
    沈念sama閱讀 43,976評論 3 448
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 43,139評論 0 290
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 49,686評論 1 336
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 41,411評論 3 358
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發(fā)現(xiàn)自己被綠了。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 43,641評論 1 374
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情,我是刑警寧澤,帶...
    沈念sama閱讀 39,129評論 5 364
  • 正文 年R本政府宣布,位于F島的核電站,受9級特大地震影響,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點故事閱讀 44,820評論 3 350
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧,春花似錦、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 35,233評論 0 28
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 36,567評論 1 295
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人。 一個月前我還...
    沈念sama閱讀 52,362評論 3 400
  • 正文 我出身青樓,卻偏偏與公主長得像,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點故事閱讀 48,604評論 2 380

推薦閱讀更多精彩內(nèi)容