攔截器和過濾器詳解

過濾器和攔截器的區(qū)別:

  1. 攔截器是基于java的反射機(jī)制的蒸其,而過濾器是基于函數(shù)回調(diào)哺窄。
  2. 攔截器不依賴與servlet容器字柠,過濾器依賴與servlet容器绑榴。
  3. 攔截器只能對action請求起作用,而過濾器則可以對幾乎所有的請求起作用蹂午。
  4. 攔截器可以訪問action上下文栏豺、值棧里的對象,而過濾器不能訪問豆胸。
  5. 在action的生命周期中奥洼,攔截器可以多次被調(diào)用,而過濾器只能在容器初始化時(shí)被調(diào)用一次晚胡。
  6. 攔截器可以獲取IOC容器中的各個(gè)bean灵奖,而過濾器就不行,這點(diǎn)很重要估盘,在攔截器里注入一個(gè)service瓷患,可以調(diào)用業(yè)務(wù)邏輯。

攔截器可以獲取ioc中的service bean實(shí)現(xiàn)業(yè)務(wù)邏輯忿檩,攔截器可以獲取ioc中的service bean實(shí)現(xiàn)業(yè)務(wù)邏輯尉尾,攔截器可以獲取ioc中的service bean實(shí)現(xiàn)業(yè)務(wù)邏輯,

觸發(fā)時(shí)機(jī):

  • 過濾器是在請求進(jìn)入容器后燥透,但請求進(jìn)入servlet之前進(jìn)行預(yù)處理的。請求結(jié)束返回也是辨图,是在servlet處理完后班套,返回給前端之前。
  • 過濾器的觸發(fā)時(shí)機(jī)是容器后故河,servlet之前吱韭,所以過濾器的doFilter(
    ServletRequest request, ServletResponse response, FilterChain chain
    )的入?yún)⑹荢ervletRequest ,而不是httpservletrequest。因?yàn)檫^濾器是在httpservlet之前理盆。
  • 過濾器
    @Override
    public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {
    System.out.println("before...");
    chain.doFilter(request, response);
    System.out.println("after...");
    }
    chain.doFilter(request, response);這個(gè)方法的調(diào)用作為分水嶺痘煤。事實(shí)上調(diào)用Servlet的doService()方法是在chain.doFilter(request, response);這個(gè)方法中進(jìn)行的。

總結(jié):過濾器包裹住servlet猿规,servlet包裹住攔截器衷快。

執(zhí)行順序圖

1.過濾器是JavaEE標(biāo)準(zhǔn),采用函數(shù)回調(diào)的方式進(jìn)行姨俩。是在請求進(jìn)入容器之后蘸拔,還未進(jìn)入Servlet之前進(jìn)行預(yù)處理,并且在請求結(jié)束返回給前端這之間進(jìn)行后期處理环葵。

@Override
    public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {
        System.out.println("before...");
        chain.doFilter(request, response);
        System.out.println("after...");
    }

chain.doFilter(request, response);這個(gè)方法的調(diào)用作為分水嶺调窍。事實(shí)上調(diào)用Servlet的doService()方法是在chain.doFilter(request, response);這個(gè)方法中進(jìn)行的。

2.攔截器是被包裹在過濾器之中的张遭。

@Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
        System.out.println("preHandle");
        return true;
    }

    @Override
    public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception {
        System.out.println("postHandle");
    }

    @Override
    public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception {
        System.out.println("afterCompletion");
    }

preHandle()這個(gè)方法是在過濾器的chain.doFilter(request, response)方法的前一步執(zhí)行邓萨,也就是在 [System.out.println("before...")][chain.doFilter(request, response)]之間執(zhí)行。
preHandle()方法之后菊卷,在return ModelAndView之前進(jìn)行缔恳,可以操控Controller的ModelAndView內(nèi)容。
afterCompletion()方法是在過濾器返回給前端前一步執(zhí)行的烁,也就是在[chain.doFilter(request, response)][System.out.println("after...")]之間執(zhí)行褐耳。

3.SpringMVC的機(jī)制是由同一個(gè)Servlet來分發(fā)請求給不同的Controller,其實(shí)這一步是在Servlet的service()方法中執(zhí)行的渴庆。所以過濾器铃芦、攔截器、service()方法襟雷,dispatc()方法的執(zhí)行順序應(yīng)該是這樣的刃滓,大致畫了個(gè)圖:其實(shí)非常好測試,自己寫一個(gè)過濾器耸弄,一個(gè)攔截器咧虎,然后在這些方法中都加個(gè)斷點(diǎn),一路F8下去就得出了結(jié)論计呈。
4.SpringMVC的機(jī)制是由同一個(gè)Servlet來分發(fā)請求給不同的Controller砰诵,其實(shí)這一步是在Servlet的service()方法中執(zhí)行的。
5.捌显,SpringMVC的機(jī)制是由同一個(gè)Servlet來分發(fā)請求給不同的Controller茁彭,其實(shí)這一步是在Servlet的service()方法中執(zhí)行的。
6.SpringMVC的機(jī)制是由同一個(gè)Servlet來分發(fā)請求給不同的Controller扶歪,其實(shí)這一步是在Servlet的service()方法中執(zhí)行的理肺。
7.還有,攔截器是spring容器的,是spring支持的妹萨,


執(zhí)行機(jī)制

總結(jié):攔截器功在對請求權(quán)限鑒定方面確實(shí)很有用處年枕,在我所參與的這個(gè)項(xiàng)目之中,第三方的遠(yuǎn)程調(diào)用每個(gè)請求都需要參與鑒定乎完,所以這樣做非常方便熏兄,而且他是很獨(dú)立的邏輯,這樣做讓業(yè)務(wù)邏輯代碼很干凈囱怕。和框架的其他功能一樣霍弹,原理很簡單,使用起來也很簡單娃弓,大致看了下SpringMVC這一部分的源碼典格,其實(shí)還是比較容易理解的。

我們項(xiàng)目中僅僅用到了preHandle這個(gè)方法台丛,而未用其他的耍缴,框架提供了一個(gè)已經(jīng)實(shí)現(xiàn)了攔截器接口的適配器類HandlerInterceptorAdapter,繼承這個(gè)類然后重寫一下需要用到的方法就行了挽霉,可以少幾行代碼防嗡,這種方式Java中很多地方都有體現(xiàn)。


攔截器和過濾器

本文整理于:https://www.cnblogs.com/panxuejun/p/7715917.html

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末侠坎,一起剝皮案震驚了整個(gè)濱河市蚁趁,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌实胸,老刑警劉巖他嫡,帶你破解...
    沈念sama閱讀 211,561評(píng)論 6 492
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異庐完,居然都是意外死亡钢属,警方通過查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 90,218評(píng)論 3 385
  • 文/潘曉璐 我一進(jìn)店門门躯,熙熙樓的掌柜王于貴愁眉苦臉地迎上來淆党,“玉大人,你說我怎么就攤上這事讶凉∪疚冢” “怎么了?”我有些...
    開封第一講書人閱讀 157,162評(píng)論 0 348
  • 文/不壞的土叔 我叫張陵懂讯,是天一觀的道長慕匠。 經(jīng)常有香客問我,道長域醇,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 56,470評(píng)論 1 283
  • 正文 為了忘掉前任,我火速辦了婚禮譬挚,結(jié)果婚禮上锅铅,老公的妹妹穿的比我還像新娘。我一直安慰自己减宣,他們只是感情好盐须,可當(dāng)我...
    茶點(diǎn)故事閱讀 65,550評(píng)論 6 385
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著漆腌,像睡著了一般贼邓。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上闷尿,一...
    開封第一講書人閱讀 49,806評(píng)論 1 290
  • 那天塑径,我揣著相機(jī)與錄音,去河邊找鬼填具。 笑死统舀,一個(gè)胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的劳景。 我是一名探鬼主播誉简,決...
    沈念sama閱讀 38,951評(píng)論 3 407
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼盟广!你這毒婦竟也來了闷串?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 37,712評(píng)論 0 266
  • 序言:老撾萬榮一對情侶失蹤筋量,失蹤者是張志新(化名)和其女友劉穎烹吵,沒想到半個(gè)月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體毛甲,經(jīng)...
    沈念sama閱讀 44,166評(píng)論 1 303
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡年叮,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 36,510評(píng)論 2 327
  • 正文 我和宋清朗相戀三年,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了玻募。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片只损。...
    茶點(diǎn)故事閱讀 38,643評(píng)論 1 340
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡,死狀恐怖七咧,靈堂內(nèi)的尸體忽然破棺而出跃惫,到底是詐尸還是另有隱情,我是刑警寧澤艾栋,帶...
    沈念sama閱讀 34,306評(píng)論 4 330
  • 正文 年R本政府宣布爆存,位于F島的核電站,受9級(jí)特大地震影響蝗砾,放射性物質(zhì)發(fā)生泄漏先较。R本人自食惡果不足惜携冤,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 39,930評(píng)論 3 313
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望闲勺。 院中可真熱鬧曾棕,春花似錦、人聲如沸菜循。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,745評(píng)論 0 21
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽癌幕。三九已至衙耕,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間勺远,已是汗流浹背橙喘。 一陣腳步聲響...
    開封第一講書人閱讀 31,983評(píng)論 1 266
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留谚中,地道東北人渴杆。 一個(gè)月前我還...
    沈念sama閱讀 46,351評(píng)論 2 360
  • 正文 我出身青樓,卻偏偏與公主長得像宪塔,于是被迫代替她去往敵國和親磁奖。 傳聞我的和親對象是個(gè)殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 43,509評(píng)論 2 348

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