JavaWeb基礎(chǔ)之Filter詳解

Filter也稱之為過濾器,如下圖所示,瀏覽器在訪問web資源時折砸,如果服務(wù)器配置了過濾器,則該訪問在獲取到web資源之間會經(jīng)過過濾器沙峻,在訪問完后又會回到過濾器睦授,最后經(jīng)過服務(wù)器才返回瀏覽器。通過這種方法摔寨,我們可以實現(xiàn)權(quán)限訪問控制去枷、過濾敏感詞匯、壓縮響應(yīng)信息等一些高級功能是复。

1.Filter開發(fā)步驟

開發(fā)過濾器很簡單删顶,只需要經(jīng)過編寫java類,進(jìn)行相關(guān)配置淑廊,就可以使用了逗余。

1.1 編寫java類

Servlet API中提供了一個Filter接口,我們通過實現(xiàn)該接口重寫里面的方法就可以實現(xiàn)過濾器的功能。

import java.io.IOException;
import java.util.Enumeration;

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 HelloFilter implements Filter{
    
    // 創(chuàng)建實例
    public HelloFilter(){
        System.out.println("1. 創(chuàng)建過濾器實例");
    }

    @Override
    public void init(FilterConfig filterConfig) throws ServletException {
        System.out.println("2. 執(zhí)行過濾器初始化方法");
        
        // 獲取過濾器在web.xml中配置的初始化參數(shù)
        String encoding = filterConfig.getInitParameter("encoding");
        System.out.println(encoding);
        
        // 獲取過濾器在web.xml中配置的初始化參數(shù) 的名稱
        Enumeration<String> enums =  filterConfig.getInitParameterNames();
        while (enums.hasMoreElements()){
            // 獲取所有參數(shù)名稱:encoding蒋纬、path
            String name = enums.nextElement();
            // 獲取名稱對應(yīng)的值
            String value = filterConfig.getInitParameter(name);
            System.out.println(name + "\t" + value);
        }
    }

    // 過濾器業(yè)務(wù)處理方法: 在請求到達(dá)servlet之前先進(jìn)入此方法處理公用的業(yè)務(wù)邏輯操作
    @Override
    public void doFilter(ServletRequest request, ServletResponse response,
            FilterChain chain) throws IOException, ServletException {
        System.out.println("3. 執(zhí)行過濾器業(yè)務(wù)處理方法");
        // 放行 (去到Servlet)
        // 如果有下一個過濾器猎荠,進(jìn)入下一個過濾器,否則就執(zhí)行訪問servlet
        chain.doFilter(request, response);
        
        System.out.println("5. Servlet處理完成蜀备,又回到過濾器");
    }

    @Override
    public void destroy() {
        System.out.println("6. 銷毀過濾器實例");
    }

}

1.2 進(jìn)行相關(guān)配置

在web.xml中添加如下內(nèi)容:

    <filter>
        <!-- 過濾器名稱  -->
        <filter-name>hello_filter</filter-name>
        
        <!-- 過濾器對應(yīng)的實現(xiàn)類  -->
        <filter-class>cn.itcast.a_filter_hello.HelloFilter</filter-class>
        
        <!-- 過濾器初始化參數(shù)   -->
        <init-param>
            <param-name>encoding</param-name>
            <param-value>UTF-8</param-value>
        </init-param>
        <init-param>
            <param-name>path</param-name>
            <param-value>c:/...</param-value>
        </init-param>
    </filter>
    <filter-mapping>
        <filter-name>hello_filter</filter-name>
        
        <!-- 過濾器過濾模式关摇,/* 表示過濾所有資源    -->
        <url-pattern>/*</url-pattern>
    </filter-mapping>

** 輔助servlet:**

public class ServletTest extends HttpServlet {
    public void doGet(HttpServletRequest request, HttpServletResponse response)
            throws ServletException, IOException {
        System.out.println("I'm a test servlet!");
    }
}

當(dāng)我們兩次訪問輔助測試servlet時效果如下:

2.FilterChain

即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)資源整袁。

3.Filter生命周期

通過上面實例菠齿, 可以看到在啟動tomcat服務(wù)器時就執(zhí)行了過濾器的構(gòu)造方法和初始化方法,在每次訪問servlet時都會進(jìn)入doFilter()方法坐昙,訪問完servlet方法后又會返回到doFilter()方法绳匀,而destroy()方法只在停止服務(wù)器時才會執(zhí)行一次。

下圖通過時序圖展示了有兩個過濾器的Filter執(zhí)行流程:

4.Filter映射

<filter-mapping>元素用于設(shè)置一個 Filter 所負(fù)責(zé)攔截的資源炸客。一個Filter攔截的資源可通過兩種方式來指定:Servlet 名稱和資源訪問的請求路徑

<filter-name>子元素用于設(shè)置filter的注冊名稱疾棵。該值必須是在<filter>元素中聲明過的過濾器的名字
<filter-name>hello_filter</filter-name>

<url-pattern>設(shè)置 filter 所攔截的請求路徑(過濾器關(guān)聯(lián)的URL樣式)

<!-- 攔截指定的jsp  -->
     <url-pattern>/index.jsp</url-pattern>
     <url-pattern>/list.jsp</url-pattern>
         
<!-- 攔截所有的jsp -->
     <url-pattern>*.jsp</url-pattern>

<servlet-name>指定過濾器所攔截的Servlet名稱。

<!-- 3. 根據(jù)servlet的內(nèi)部名稱攔截 -->
     <servlet-name>IndexServlet</servlet-name>         
<!-- 攔截指定的servlet  -->
     <url-pattern>/index</url-pattern>

<dispatcher>指定過濾器所攔截的資源被 Servlet 容器調(diào)用的方式嚷量,可以是REQUEST,INCLUDE,FORWARD和ERROR之一陋桂,默認(rèn)REQUEST。用戶可以設(shè)置多個<dispatcher> 子元素用來指定 Filter 對資源的多種調(diào)用方式進(jìn)行攔截蝶溶。

<!-- 攔截直接訪問的請求或者重定向的資源  -->
     <dispatcher>REQUEST</dispatcher>
     <dispatcher>FORWARD</dispatcher>

<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)用瀑志。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市,隨后出現(xiàn)的幾起案子劈猪,更是在濱河造成了極大的恐慌昧甘,老刑警劉巖,帶你破解...
    沈念sama閱讀 211,123評論 6 490
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件战得,死亡現(xiàn)場離奇詭異充边,居然都是意外死亡,警方通過查閱死者的電腦和手機(jī)贡避,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 90,031評論 2 384
  • 文/潘曉璐 我一進(jìn)店門痛黎,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人刮吧,你說我怎么就攤上這事∫锤颍” “怎么了杀捻?”我有些...
    開封第一講書人閱讀 156,723評論 0 345
  • 文/不壞的土叔 我叫張陵,是天一觀的道長蚓庭。 經(jīng)常有香客問我致讥,道長,這世上最難降的妖魔是什么器赞? 我笑而不...
    開封第一講書人閱讀 56,357評論 1 283
  • 正文 為了忘掉前任垢袱,我火速辦了婚禮,結(jié)果婚禮上港柜,老公的妹妹穿的比我還像新娘请契。我一直安慰自己,他們只是感情好夏醉,可當(dāng)我...
    茶點故事閱讀 65,412評論 5 384
  • 文/花漫 我一把揭開白布爽锥。 她就那樣靜靜地躺著,像睡著了一般畔柔。 火紅的嫁衣襯著肌膚如雪氯夷。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 49,760評論 1 289
  • 那天靶擦,我揣著相機(jī)與錄音腮考,去河邊找鬼。 笑死玄捕,一個胖子當(dāng)著我的面吹牛踩蔚,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播桩盲,決...
    沈念sama閱讀 38,904評論 3 405
  • 文/蒼蘭香墨 我猛地睜開眼寂纪,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起捞蛋,我...
    開封第一講書人閱讀 37,672評論 0 266
  • 序言:老撾萬榮一對情侶失蹤孝冒,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后拟杉,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體庄涡,經(jīng)...
    沈念sama閱讀 44,118評論 1 303
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 36,456評論 2 325
  • 正文 我和宋清朗相戀三年搬设,在試婚紗的時候發(fā)現(xiàn)自己被綠了穴店。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 38,599評論 1 340
  • 序言:一個原本活蹦亂跳的男人離奇死亡拿穴,死狀恐怖泣洞,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情默色,我是刑警寧澤球凰,帶...
    沈念sama閱讀 34,264評論 4 328
  • 正文 年R本政府宣布,位于F島的核電站腿宰,受9級特大地震影響呕诉,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜吃度,卻給世界環(huán)境...
    茶點故事閱讀 39,857評論 3 312
  • 文/蒙蒙 一甩挫、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧椿每,春花似錦伊者、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,731評論 0 21
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至兑牡,卻和暖如春央碟,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背均函。 一陣腳步聲響...
    開封第一講書人閱讀 31,956評論 1 264
  • 我被黑心中介騙來泰國打工亿虽, 沒想到剛下飛機(jī)就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人苞也。 一個月前我還...
    沈念sama閱讀 46,286評論 2 360
  • 正文 我出身青樓洛勉,卻偏偏與公主長得像,于是被迫代替她去往敵國和親如迟。 傳聞我的和親對象是個殘疾皇子收毫,可洞房花燭夜當(dāng)晚...
    茶點故事閱讀 43,465評論 2 348

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

  • 本文包括:1攻走、Filter簡介2、Filter是如何實現(xiàn)攔截的此再?3昔搂、Filter開發(fā)入門4、Filter的生命周期...
    廖少少閱讀 7,256評論 3 56
  • 監(jiān)聽器(listener) 監(jiān)聽器簡介 :監(jiān)聽器就是一個實現(xiàn)特定接口的普通java程序输拇,這個程序?qū)iT用于監(jiān)聽另一個...
    奮斗的老王閱讀 2,498評論 0 53
  • 1.過濾器簡介 Filter也稱之為過濾器摘符,它是Servlet技術(shù)中最激動人心的技術(shù),WEB開發(fā)人員通過Filte...
    胖先森閱讀 1,131評論 0 16
  • Filters是Java組件策吠,它們在從請求到資源及從資源到響應(yīng)上允許有效負(fù)荷與頭部信息的傳遞逛裤。 本章描述了Java...
    Lucky_Micky閱讀 844評論 0 0
  • 很多人說計劃趕不上變化,但如果沒有計劃猴抹,生活就如有生命的體現(xiàn)带族。昏昏沉沉渾渾噩噩蟀给,過了這一生炉菲。 我希望我的一生過得那...
    孤獨是孤獨者的盛裝閱讀 284評論 0 0