12派任、過濾器與監(jiān)聽器

一 砸逊、過濾器(filter)

1、概要

在源數(shù)據(jù)和目的數(shù)據(jù)之間起過濾作用的中間組件

當(dāng)web容器接收到一個對資源的請求時掌逛,它將判斷是否有過濾器與這個資源相關(guān)师逸,如果有拦盹,那么容器將請求交給過濾器進行處理殊霞。在過濾器中洲尊,可以改變請求的內(nèi)容或者重新設(shè)置請求的報頭信息竿刁,然后再將請求發(fā)送給目標(biāo)資源。當(dāng)目標(biāo)資源對請求作出響應(yīng)時神得,容器同樣會將響應(yīng)轉(zhuǎn)發(fā)給過濾器锌介。然后發(fā)送到客戶端**

2令哟、web.xml 中聲明的每個 filter 在每個虛擬機中僅僅只有一個實例心傀。

Web 容器啟動時屈暗,即會根據(jù) web.xml 中聲明的 filter 順序依次實例化這些 filter拆讯。

  1. 初始化

    Web 容器調(diào)用 init(FilterConfig) 來初始化過濾器脂男。容器在調(diào)用該方法時,向過濾器傳遞 FilterConfig 對象种呐,F(xiàn)ilterConfig 的用法和 ServletConfig 類似宰翅。利用 FilterConfig 對象可以得到 ServletContext 對象,以及在 web.xml 中配置的過濾器的初始化參數(shù)爽室。在這個方法中汁讼,可以拋出 ServletException 異常,通知容器該過濾器不能正常工作阔墩。此時的 Web 容器啟動失敗嘿架,整個應(yīng)用程序不能夠被訪問。實例化和初始化的操作只會在容器啟動時執(zhí)行啸箫,而且只會執(zhí)行一次耸彪。

  2. doFilter

    doFilter 方法類似于 Servlet 接口的 service 方法。當(dāng)客戶端請求目標(biāo)資源的時候忘苛,容器會篩選出符合 filter-mapping 中的 url-pattern 的 filter蝉娜,并按照聲明 filter-mapping 的順序依次調(diào)用這些 filter 的 doFilter 方法唱较。在這個鏈?zhǔn)秸{(diào)用過程中,可以調(diào)用 chain.doFilter(ServletRequest, ServletResponse) 將請求傳給下一個過濾器(或目標(biāo)資源)召川,也可以直接向客戶端返回響應(yīng)信息南缓,或者利用 RequestDispatcher 的 forward 和 include 方法,以及 HttpServletResponse 的 sendRedirect 方法將請求轉(zhuǎn)向到其它資源荧呐。需要注意的是汉形,這個方法的請求和響應(yīng)參數(shù)的類型是 ServletRequest 和 ServletResponse,也就是說倍阐,過濾器的使用并不依賴于具體的協(xié)議获雕。

  3. 銷毀

    Web 容器調(diào)用 destroy 方法指示過濾器的生命周期結(jié)束。在這個方法中收捣,可以釋放過濾器使用的資源届案。

3、接口相關(guān)接口介紹

1罢艾、Filter接口

  1. init(FilterConfig filterConfig)
    初始化過濾器楣颠。filterconfig用來獲取ServletContext,初始化參數(shù)。
  2. doFilter(ServletRequest request,ServletResponse response,FilterChain chain);
    實現(xiàn)過濾功能咐蚯⊥觯可以調(diào)用chain.doFilter(request,response)方法將請求傳遞給下一個過濾器或者目標(biāo)資源,也可以直接向客戶端返回響應(yīng)信息春锋。
  3. destory()
    結(jié)束過濾器的聲明周期矫膨。

2、FilterConfig接口

  1. getInitParameter(String name)
    返回名為name的初始化參數(shù)的值
  2. getInitParameterNames()
    返回所有初始化參數(shù)的名字的枚舉集合期奔。
  3. getServletContext()
    返回Servlet上下文對象的引用
    

3侧馅、FilterChain接口

  1. doFilter(ServletRequest request,ServletResponse response)
    調(diào)用該方法將使過濾器鏈中的下一個過濾器被調(diào)用,如果該方法時過濾器鏈中最后一個過濾器呐萌,那么目標(biāo)資源被調(diào)用

4馁痴、簡單使用

4.1、Filter開發(fā)分為2步:

編寫java類實現(xiàn)Filter接口肺孤,并實現(xiàn)其doFilter方法罗晕。

在web.xml 文件中使用和元素對編寫的filter類進行注冊,并設(shè)置它所能攔截的資源赠堵。

4.2小渊、示例代碼

  1. java代碼
    public class CharsetFilter implements Filter {
        @Override
        public void init(FilterConfig filterConfig) throws ServletException {
        }
        @Override
        public void doFilter(ServletRequest request, ServletResponse response, FilterChain filterChain) throws IOException, ServletException {
            // 對request、response進行一些預(yù)處理
            request.setCharacterEncoding("utf-8");
            response.setContentType("text/html ; charset=utf-8");
            //繼續(xù)攔截
            filterChain.doFilter(request, response);
        }
     @Override
        public void destroy() {
        }
    

}

2. 在web.xml中注冊
```xml
    <filter-name>charset-filter</filter-name>
    <filter-class>com.werner.demo.filter.CharsetFilter</filter-class>
    <init-param>
        <param-name>charset</param-name>
        <param-value>UTF-8</param-value>
    </init-param>
    <init-param>
        <param-name>enable</param-name>
        <param-value>true</param-value>
    </init-param>
</filter>
<filter-mapping>
    <filter-name>charset-filter</filter-name>
    <url-pattern>/servlet/*</url-pattern>
    <url-pattern>/l</url-pattern>
    <dispatcher>REQUEST</dispatcher>
</filter-mapping>
  <servlet>
       <servlet-name>Filter</servlet-name>
       <servlet-class>com.werner.demo.servlet.HttpServletFilter</servlet-class>
   </servlet>
   <servlet-mapping>
       <servlet-name>Filter</servlet-name>
       <url-pattern>/l</url-pattern>
   </servlet-mapping>
  1. 說明:
    • <filter>:配置 Filter 名稱茫叭,實現(xiàn)類以及初始化參數(shù)酬屉。可以同時配置多個初始化參數(shù)杂靶。
    • <filter-mapping>:配置什么規(guī)則下使用這個Filter 梆惯。
      • <url-pattern> :`配置url的規(guī)則酱鸭,可以配置多個,也可以使用通配符()垛吗。例如 /jsp/ 適用于本ContextPath下以“/jsp/ ”開頭的所有servlet路徑凹髓, *.do 適用于所有以“ .do”結(jié)尾的servlet路徑。
      • <dispatcher> :配置到達servlet的方式怯屉,可以同時配置多個蔚舀。有四種取值:REQUEST、FORWARD锨络、ERROR赌躺、INCLUDE。如果沒有配置羡儿,則默認(rèn)為REQUEST礼患。它們的區(qū)別是:
        • REQUEST :表示僅當(dāng)直接請求servlet時才生效。
        • FORWARD :表示僅當(dāng)某servlet通過forward轉(zhuǎn)發(fā)到該servlet時才生效掠归。
          {0}. INCLUDE :Jsp中可以通過<jsp:include/>請求某servlet缅叠, 只有這種情況才有效。
          {0}. ERROR :Jsp中可以通過<%@page errorPage="error.jsp" %>指定錯誤處理頁面虏冻,僅在這種情況下才生效肤粱。

5、Filter應(yīng)用場景

1厨相、統(tǒng)一POST請求中文字符編碼的過濾器 2领曼、控制瀏覽器緩存頁面中的靜態(tài)資源的過濾器

有些動態(tài)頁面中引用了一些圖片或css文件以修飾頁面效果,這些圖片和css文件經(jīng)常是不變化的蛮穿,所以為減輕服務(wù)器的壓力庶骄,可以使用filter控制瀏覽器緩存這些文件,以提升服務(wù)器的性能绪撵。
3瓢姻、使用Filter實現(xiàn)URL級別的權(quán)限認(rèn)證
在實際開發(fā)中我們經(jīng)常把一些執(zhí)行敏感操作的servlet映射到一些特殊目錄中祝蝠,并用filter把這些特殊目錄保護起來音诈,限制只能擁有相應(yīng)訪問權(quán)限的用戶才能訪問這些目錄下的資源。從而在我們系統(tǒng)中實現(xiàn)一種URL級別的權(quán)限功能绎狭。
4细溅、實現(xiàn)用戶自動登陸
首先,在用戶登陸成功后儡嘶,發(fā)送一個名稱為user的cookie給客戶端喇聊,cookie的值為用戶名和md5加密后的密碼。編寫一個AutoLoginFilter蹦狂,這個filter檢查用戶是否帶有名稱為user的cookie誓篱,如果有朋贬,則調(diào)用dao查詢cookie的用戶名和密碼是否和數(shù)據(jù)庫匹配,匹配則向session中存入user對象(即用戶登陸標(biāo)記)窜骄,以實現(xiàn)程序完成自動登陸锦募。
5、認(rèn)證Filter
6邻遏、日志和審核Filter
7糠亩、圖片轉(zhuǎn)換Filter
8、數(shù)據(jù)壓縮Filter
8准验、密碼Filter
9赎线、令牌Filter

二、監(jiān)聽器

2.1糊饱、說明

Servlet API中定義了8個監(jiān)聽器接口垂寥,可以用于監(jiān)聽ServletContext,HttpSession,ServletRequest對象的生命周期事件。

  1. ServletContextListener 監(jiān)聽Servlet上下文對象初始化或者被銷毀
  2. ServletContextAttributeListener 監(jiān)聽Servlet上下文中的屬性列表的變化
  3. HttpSessionListener 監(jiān)聽Session生命周期
  4. HttpSessionActionListener 監(jiān)聽session被鈍化或者激活
  5. HttpSessionAttributeListener 監(jiān)聽Session屬性列表發(fā)生的變化
  6. HttpSessionBindingListener 監(jiān)聽Session中是否有對象綁定或者刪除另锋,該對象要實現(xiàn)這個接口
  7. ServletRequestListener 監(jiān)聽ServletRequest對象生命周期
  8. ServletRequestAttributeListener 監(jiān)聽ServletRequest屬性列表發(fā)生的變化

2.2矫废、詳細解釋

  1. ServletContextListener 監(jiān)聽ServletContext的啟動或者銷毀
  2. contextInitialized(ServletContextEvent sce)
    當(dāng)web應(yīng)用程序初始化進程正開始時,web容器調(diào)用這個方法砰蠢,該方法將在所有的過濾器和Servlet初始化之前被調(diào)用蓖扑。contextDestroyed(ServletContextEvent sce)當(dāng)Servlet上下文將要關(guān)閉時,Web容器調(diào)用這個方法台舱,該方法在所有Servlet和和過濾器銷毀之后被調(diào)用律杠。
    例子: 在Web應(yīng)用程序啟動時初始化DataSource對象,然后將其方法ServletContext中 數(shù)據(jù)庫支持更換
  3. HttpSessionBindingListener竞惋,(無序配置)
    如果一個對象實現(xiàn)了HttpSessionBindingListener接口柜去,當(dāng)這個對象被綁定的Session或者從Session中被刪除時,Servlet容器就會通知這個對象拆宛。
    1. valueBound(HttpSessionBindingEvent event)
      當(dāng)對象正在被綁定到Session中嗓奢,Servlet容器調(diào)用這個方法通知該對象
    2. valueUnBound(HttpSessionBindingEvent event)
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市浑厚,隨后出現(xiàn)的幾起案子股耽,更是在濱河造成了極大的恐慌,老刑警劉巖钳幅,帶你破解...
    沈念sama閱讀 219,110評論 6 508
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件物蝙,死亡現(xiàn)場離奇詭異,居然都是意外死亡敢艰,警方通過查閱死者的電腦和手機诬乞,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,443評論 3 395
  • 文/潘曉璐 我一進店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人震嫉,你說我怎么就攤上這事森瘪。” “怎么了票堵?”我有些...
    開封第一講書人閱讀 165,474評論 0 356
  • 文/不壞的土叔 我叫張陵柜砾,是天一觀的道長。 經(jīng)常有香客問我换衬,道長痰驱,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 58,881評論 1 295
  • 正文 為了忘掉前任瞳浦,我火速辦了婚禮担映,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘叫潦。我一直安慰自己蝇完,他們只是感情好,可當(dāng)我...
    茶點故事閱讀 67,902評論 6 392
  • 文/花漫 我一把揭開白布矗蕊。 她就那樣靜靜地躺著短蜕,像睡著了一般。 火紅的嫁衣襯著肌膚如雪傻咖。 梳的紋絲不亂的頭發(fā)上朋魔,一...
    開封第一講書人閱讀 51,698評論 1 305
  • 那天,我揣著相機與錄音卿操,去河邊找鬼警检。 笑死,一個胖子當(dāng)著我的面吹牛害淤,可吹牛的內(nèi)容都是我干的扇雕。 我是一名探鬼主播,決...
    沈念sama閱讀 40,418評論 3 419
  • 文/蒼蘭香墨 我猛地睜開眼窥摄,長吁一口氣:“原來是場噩夢啊……” “哼镶奉!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起崭放,我...
    開封第一講書人閱讀 39,332評論 0 276
  • 序言:老撾萬榮一對情侶失蹤哨苛,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后莹菱,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體移国,經(jīng)...
    沈念sama閱讀 45,796評論 1 316
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 37,968評論 3 337
  • 正文 我和宋清朗相戀三年道伟,在試婚紗的時候發(fā)現(xiàn)自己被綠了。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 40,110評論 1 351
  • 序言:一個原本活蹦亂跳的男人離奇死亡蜜徽,死狀恐怖祝懂,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情拘鞋,我是刑警寧澤砚蓬,帶...
    沈念sama閱讀 35,792評論 5 346
  • 正文 年R本政府宣布,位于F島的核電站盆色,受9級特大地震影響灰蛙,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜隔躲,卻給世界環(huán)境...
    茶點故事閱讀 41,455評論 3 331
  • 文/蒙蒙 一摩梧、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧宣旱,春花似錦仅父、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 32,003評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至组力,卻和暖如春省容,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背燎字。 一陣腳步聲響...
    開封第一講書人閱讀 33,130評論 1 272
  • 我被黑心中介騙來泰國打工蓉冈, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人轩触。 一個月前我還...
    沈念sama閱讀 48,348評論 3 373
  • 正文 我出身青樓寞酿,卻偏偏與公主長得像,于是被迫代替她去往敵國和親脱柱。 傳聞我的和親對象是個殘疾皇子伐弹,可洞房花燭夜當(dāng)晚...
    茶點故事閱讀 45,047評論 2 355

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