SpringBoot: Filter vs HandlerInterceptor 宵统?

歡迎關(guān)注公眾號(hào):邏魔代碼

我們知道晕讲,在Java Web開發(fā)時(shí),若想對(duì)請(qǐng)求或響應(yīng)做出統(tǒng)一的邏輯處理马澈,可以使用過濾器或者攔截器瓢省。那么具體什么時(shí)候使用過濾器,什么時(shí)候使用攔截器呢痊班?

在探究這個(gè)問題之前勤婚,我們先搞清楚,什么是 Servlet 涤伐?

Servlet

現(xiàn)在我們通常做 Java Web 開發(fā)都會(huì)用 SpringBoot 馒胆,但要知道 SpringBoot 只是用來簡化開發(fā)的荆永,在此之前,Springframework 只是一個(gè)粘合劑框架国章,用來整合各種 Java Web 技術(shù)的具钥,SpringMvc 都是出現(xiàn)的比較晚的技術(shù),更早之前是 Struts2液兽、Struts1骂删。

那更早之前呢?就是基于原始的 Servlet/JSP 四啰。

javax.servletjaavx.servlet.http 包提供了一些接口和類宁玫,實(shí)現(xiàn)了 Servlet 規(guī)范。 javax.servlet 包中的 Servlet 聲明了一些重要方法柑晒,如 init(), service(), desctroy() 等欧瘪,這些也都是 servlet 的生命周期方法.

我們還知道,Servlet 是運(yùn)行于 Servlet 容器中的匙赞。容器可以處理網(wǎng)絡(luò)連接佛掖,解析 HTTP 請(qǐng)求等。Tomcat 就是最負(fù)盛名的一個(gè)容器涌庭。

雖然現(xiàn)在大家都用 Spring 全家桶做開發(fā)芥被,但必須要知道 SpringWvc 的核心還是一個(gè) DispatcherServlet,其本質(zhì)也就是一個(gè) Servlet.

過濾器 Filter

過濾器是被容器執(zhí)行的類坐榆。請(qǐng)求在進(jìn)入容器時(shí)拴魄、響應(yīng)在離開容器時(shí),會(huì)經(jīng)過一個(gè)個(gè)的過濾器席镀。過濾器的實(shí)例匹中,在容器中是以過濾器鏈的形式執(zhí)行的。

如果在應(yīng)用中豪诲,我們定義了多個(gè)過濾器顶捷,那么執(zhí)行的先后順序,可以通過 @Order 注解來指定跛溉。

Filter 接口的核心方法焊切,也是其生命周期方法:

  • init(FilterConfig config) - 此方法只調(diào)用一次,用于初始化過濾器
  • doFilter(HttpServletRequest request, HttpServletResponse response, FilterChian chian) - 此方法在每一個(gè)請(qǐng)求打到映射的資源上時(shí)都會(huì)調(diào)用芳室,比如定義一個(gè) Filter 攔截 /path/* 专肪,那么每一個(gè)匹配 /path/* 訪問資源的請(qǐng)求進(jìn)來時(shí),都會(huì)執(zhí)行此方法堪侯。這個(gè)方法中就是攔截器的具體邏輯
  • destroy() - 此方法也只執(zhí)行一次嚎尤,用于銷毀過濾器
Servlet-Invocation-with-and-without-FIlters

攔截器 Interceptor

Spring 攔截器類似于 Servlet 過濾器。攔截器允許自定義預(yù)處理(Pre-Processing)伍宦,在其中可以選擇禁止對(duì)應(yīng) Handler 的執(zhí)行芽死;也允許自定義后處理(Post-Precessing)乏梁;在攔截器中可以訪問 Spring Context 上下文。

HandlerInterceptor 的核心方法:

  • preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) - 該方法在請(qǐng)求到達(dá) Controller 之前執(zhí)行操作关贵,返回一個(gè)布爾值遇骑。當(dāng)返回 false 時(shí),不再執(zhí)行對(duì)應(yīng)的 handler
  • postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) - 該方法在響應(yīng)返回客戶端之前執(zhí)行
  • afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception exception) - 該方法在請(qǐng)求和響應(yīng)流程完成之后執(zhí)行

HandlerInterceptor: 它的實(shí)例在 DispatcherServlet(javax.servlet.Servlet 的實(shí)例) 中作為請(qǐng)求處理的一部分來執(zhí)行揖曾。

注意落萎,現(xiàn)在實(shí)現(xiàn) Spring 攔截器,只需要實(shí)現(xiàn) HandlerInterceptor 接口即可炭剪,更早之前练链,接口的方法不能有默認(rèn)實(shí)現(xiàn)時(shí),是需要繼承 HandlerInteceptorAdapter 這個(gè)抽象類的奴拦,現(xiàn)在這個(gè)類已經(jīng)可以廢棄了媒鼓。

通過下面一張圖看看過濾器和攔截器的位置:

Filters-and-HandlerInterceptors

Filters vs HandlerInterceptors

  • Filter 是 Servlet 規(guī)范中的,而 HandlerInterceptor 是 Spring 中的一個(gè)概念
  • 攔截器位置相對(duì)于過濾器更靠后
  • 精細(xì)的預(yù)處理任務(wù)適用于攔截器错妖,如授權(quán)檢查等
  • 內(nèi)容處理相關(guān)或通用的流程绿鸣,非常適合用過濾器;如上傳表單站玄、zip 壓縮枚驻、圖像處理濒旦、日志記錄請(qǐng)求株旷、身份驗(yàn)證等
  • HandlerInterceptorpostHandle 方法允許我們向視圖添加更多模型對(duì)象,但不能更改 HttpServletResponse尔邓,因?yàn)樗呀?jīng)被提交了
  • 過濾器的 doFilter 方法比攔截器的 postHandle 更通用晾剖。我們可以在過濾器中改變請(qǐng)求或響應(yīng),并將其傳遞給鏈梯嗽,甚至阻止請(qǐng)求的處理
  • HandlerInterceptor 提供了比過濾器更精細(xì)的控制齿尽,因?yàn)槲覀兛梢栽L問實(shí)際的目標(biāo) handler,甚至可以檢查 handler 方法是否有某個(gè)特定的注解

歡迎關(guān)注公眾號(hào):邏魔代碼

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末灯节,一起剝皮案震驚了整個(gè)濱河市循头,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌炎疆,老刑警劉巖卡骂,帶你破解...
    沈念sama閱讀 211,194評(píng)論 6 490
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異形入,居然都是意外死亡全跨,警方通過查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 90,058評(píng)論 2 385
  • 文/潘曉璐 我一進(jìn)店門亿遂,熙熙樓的掌柜王于貴愁眉苦臉地迎上來浓若,“玉大人渺杉,你說我怎么就攤上這事∨驳觯” “怎么了是越?”我有些...
    開封第一講書人閱讀 156,780評(píng)論 0 346
  • 文/不壞的土叔 我叫張陵,是天一觀的道長碌上。 經(jīng)常有香客問我英妓,道長,這世上最難降的妖魔是什么绍赛? 我笑而不...
    開封第一講書人閱讀 56,388評(píng)論 1 283
  • 正文 為了忘掉前任蔓纠,我火速辦了婚禮,結(jié)果婚禮上吗蚌,老公的妹妹穿的比我還像新娘腿倚。我一直安慰自己,他們只是感情好蚯妇,可當(dāng)我...
    茶點(diǎn)故事閱讀 65,430評(píng)論 5 384
  • 文/花漫 我一把揭開白布敷燎。 她就那樣靜靜地躺著,像睡著了一般箩言。 火紅的嫁衣襯著肌膚如雪硬贯。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 49,764評(píng)論 1 290
  • 那天陨收,我揣著相機(jī)與錄音饭豹,去河邊找鬼。 笑死务漩,一個(gè)胖子當(dāng)著我的面吹牛拄衰,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播饵骨,決...
    沈念sama閱讀 38,907評(píng)論 3 406
  • 文/蒼蘭香墨 我猛地睜開眼翘悉,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了居触?” 一聲冷哼從身側(cè)響起妖混,我...
    開封第一講書人閱讀 37,679評(píng)論 0 266
  • 序言:老撾萬榮一對(duì)情侶失蹤,失蹤者是張志新(化名)和其女友劉穎轮洋,沒想到半個(gè)月后制市,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 44,122評(píng)論 1 303
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡砖瞧,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 36,459評(píng)論 2 325
  • 正文 我和宋清朗相戀三年息堂,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點(diǎn)故事閱讀 38,605評(píng)論 1 340
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡荣堰,死狀恐怖床未,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情振坚,我是刑警寧澤薇搁,帶...
    沈念sama閱讀 34,270評(píng)論 4 329
  • 正文 年R本政府宣布,位于F島的核電站渡八,受9級(jí)特大地震影響啃洋,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜屎鳍,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 39,867評(píng)論 3 312
  • 文/蒙蒙 一宏娄、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧逮壁,春花似錦孵坚、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,734評(píng)論 0 21
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至忧饭,卻和暖如春扛伍,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背词裤。 一陣腳步聲響...
    開封第一講書人閱讀 31,961評(píng)論 1 265
  • 我被黑心中介騙來泰國打工刺洒, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留,地道東北人亚斋。 一個(gè)月前我還...
    沈念sama閱讀 46,297評(píng)論 2 360
  • 正文 我出身青樓作媚,卻偏偏與公主長得像,于是被迫代替她去往敵國和親帅刊。 傳聞我的和親對(duì)象是個(gè)殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 43,472評(píng)論 2 348

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