過濾器和攔截器的區別,這次終於懂了

2021-02-08 java1234

點擊上方藍色字體,選擇「標星公眾號」

優質文章,第一時間送達

  作者 |  天喬巴夏丶

來源 |  urlify.cn/zu6RFz

66套java從入門到精通實戰課程分享

這個是不久前在面試的時候遇到的一個問題,當時直接懵了,兩個單拎出來,雖然不太完全,但都大概知道可以對請求進行攔截,放在一起比較,可真是頭疼。

其實之前面試完就去學習了一波,只不過那個時候沒及時總結,現在總結一下,以免日後遇到這類問題又給忘咯。

要理解這類問題,光靠死記硬背可能當時有用,過一陣子就差不多忘了。要想真的牢記,我們必須要實操一下。

Filter的使用

首先,要使用Filter,必須實現javax.servlet.Filter接口:

public interface Filter {
 //web應用加載進容器,Filter對象創建之後,執行init方法初始化,用於加載資源,只執行一次。 
    public default void init(FilterConfig filterConfig) throws ServletException {}
 //每次請求或響應被攔截時執行,可執行多次。
    public void doFilter(ServletRequest request, ServletResponse response,
            FilterChain chain) throws IOException, ServletException;
 //web應用移除容器,伺服器被正常關閉,則執行destroy方法,用於釋放資源,只執行一次。
    public default void destroy() {}
}

init和destroy是default方法,實現類可以不用實現。

doFilter必須實現,也就是說,作為一個過濾器,doFilter必須要定義。

doFlilter方法中傳進來的FilterChain對象用來調用下一個過濾器。

攔截器的使用
public interface HandlerInterceptor {
 //攔截handler的執行 --> 在HanlerMapping決定適合的handler之後,[在HandlerAdater調用handler之前執行。]
 default boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler)
   throws Exception {
  return true;
 }
 //攔截handler的執行 --> [在HandlerAdapter調用handler之後],在DispatcherServlet渲染視圖之前執行
 default void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler,
   @Nullable ModelAndView modelAndView) throws Exception {
 }
 //視圖渲染後調用,且只有preHandle結果為true,才會調用
 default void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler,
   @Nullable Exception ex) throws Exception {
 }
}

//DispatcherServlet
if (!mappedHandler.applyPreHandle(processedRequest, response)) {
    return; //遍歷所有的interceptors,調用preHandle方法,只有返回true,才能進行下去
}

// 這裡也就是處理Contrller
mv = ha.handle(processedRequest, response, mappedHandler.getHandler());

//視圖渲染
applyDefaultViewName(processedRequest, mv);
//視圖渲染之後調用
mappedHandler.applyPostHandle(processedRequest, response, mv);

過濾器與攔截器到底有啥區別呢?一、實現原理不同

過濾器的實現基於回調函數

攔截器基於Java的反射機制【動態代理】實現。

二、使用範圍不同三、觸發時機不同

這一段在HandlerInterceptor類的注釋上可以發現,兩者的觸發時機是不同的:

四、執行順序不同

同時配置了過濾器和攔截器的情形:

MyFilter1 前
MyFilter2 前
MyInterceptor1 在Controller前執行
MyInterceptor2 在Controller前執行
controller方法執行...
MyInterceptor2 Controller之後,視圖渲染之前
MyInterceptor1 Controller之後,視圖渲染之前
MyInterceptor2 視圖渲染完成之後執行
MyInterceptor1 視圖渲染完成之後執行
MyFilter2 後
MyFilter1 後

每一次都將chain對象傳入,達到最後接口回調的效果:

preHandle1 -> preHande2 -> 【Controller】 -> postHandle2 -> postHandle1 -> afterCompletion2 -> afterComplention1 preHandle按照註冊順序,後兩個與註冊順序相反。

一個攔截器的preHandle為false,則之後的所有攔截器都不會執行。

一個攔截器的preHandle為true,則這個攔截器的triggerAfterCompletion一定會執行。

只有所有的攔截器preHandler都為true,也就是正常執行,postHandle才會執行。

boolean applyPreHandle(HttpServletRequest request, HttpServletResponse response) throws Exception {
    HandlerInterceptor[] interceptors = getInterceptors();
    if (!ObjectUtils.isEmpty(interceptors)) {
        for (int i = 0; i < interceptors.length; i++) {
            HandlerInterceptor interceptor = interceptors[i];
            //一旦當前攔截器preHandle的返回值為false,那麼從上一個可用的攔截器的afterCompletion開始
            if (!interceptor.preHandle(request, response, this.handler)) {
                triggerAfterCompletion(request, response, null);
                return false; //這裡返回false意為 後續不進行下去了。
            }
            this.interceptorIndex = i;//interceptorIndex初始化為-1,只有當前攔截器preHandle為true,才會賦值當前的i。
        }
    }
    return true;
}

void applyPostHandle(HttpServletRequest request, HttpServletResponse response, @Nullable ModelAndView mv)
    throws Exception {

    HandlerInterceptor[] interceptors = getInterceptors();
    if (!ObjectUtils.isEmpty(interceptors)) {
        for (int i = interceptors.length - 1; i >= 0; i--) {
            HandlerInterceptor interceptor = interceptors[i];
            interceptor.postHandle(request, response, this.handler, mv);
        }
    }
}

void triggerAfterCompletion(HttpServletRequest request, HttpServletResponse response, @Nullable Exception ex)
    throws Exception {
    HandlerInterceptor[] interceptors = getInterceptors();
        for (int i = this.interceptorIndex; i >= 0; i--) 
}

五、控制執行順序方式不同

兩者默認都是使用註冊順序,如果想要認為控制執行的順序,方式略有不同:

@Order(2)
@Component
public class MyFilter1 implements Filter {}

@Component
public class WebAdapter implements WebMvcConfigurer {

    @Autowired
    MyInterceptor1 myInterceptor1;

    @Autowired
    MyInterceptor2 myInterceptor2;

    @Override
    public void addInterceptors(InterceptorRegistry registry) {
        registry.addInterceptor(myInterceptor1).addPathPatterns("/**").order(2);
        registry.addInterceptor(myInterceptor2).addPathPatterns("/**").order(1);
    }
}

總結

原理實現上:過濾器基於回調實現,而攔截器基於動態代理。

控制粒度上:過濾器和攔截器都能夠實現對請求的攔截功能,但是在攔截的粒度上有較大的差異,攔截器對訪問控制的粒度更細。

使用場景上:攔截器往往用於權限檢查、日誌記錄等,過濾器主要用於過濾請求中無效參數,安全校驗。

依賴容器上:過濾器依賴於Servlet容器,局限於web,而攔截器依賴於Spring框架,能夠使用Spring框架的資源,不僅限於web。

觸發時機上:過濾器在Servlet前後執行,攔截器在handler前後執行,現在大多數web應用基於Spring,攔截器更細。

粉絲福利:108本java從入門到大神精選電子書領取

👇👇👇

感謝點讚支持下哈 

相關焦點

  • Java編程:過濾器和攔截器有啥區別,這次會了!
    Filter的使用首先,要使用Filter,必須實現javax.servlet.Filter接口:init和destroy是default方法,實現類可以不用實現。doFilter必須實現,也就是說,作為一個過濾器,doFilter必須要定義。doFlilter方法中傳進來的FilterChain對象用來調用下一個過濾器。攔截器的使用過濾器與攔截器到底有啥區別呢?
  • 過濾器 和 攔截器 6個區別,別再傻傻分不清了
    周末有個小夥伴加我微信,向我請教了一個問題:老哥,「過濾器 (Filter) 和 攔截器 (Interceptor) 有啥區別啊?」 聽到題目我的第一感覺就是:「簡單」!1、實現原理不同過濾器和攔截器 底層實現方式大不相同,過濾器 是基於函數回調的,攔截器 則是基於Java的反射機制(動態代理)實現的。這裡重點說下過濾器!
  • 自清洗過濾器和反衝洗過濾器有什麼區別?
    自清洗過濾器和反衝洗過濾器,都是現在市場上全自動過濾領域裡的明星產品。雖然都是全自動過濾器,但是二者有著明顯的區別。上海久丞工業科技有限公司是世界過濾工業領域內先進的設計和製造公司,公司專長於自動和智能過濾,尤其在自清洗過濾領域佔有重要地位。以我司的AFM內刮式自清洗過濾器和AR反衝洗過濾器為例,來對二者進行比較。
  • springmvc攔截器及源碼分析
    前言springmvc攔截器是我們項目開發中用到的一個功能,常常用於對Handler進行預處理和後處理。本案例來演示一個較簡單的springmvc攔截器的使用,並通過分析源碼來探究攔截器的執行順序是如何控制的。
  • 空氣壓縮機的前置過濾器與後置過濾器有什麼區別?
    螺杆式空壓機的後處理設備,主要由儲氣罐、乾燥機及過濾器組成。而在過濾器部分中,又分為前置過濾器和後置過濾器,一般是由乾燥機隔開,壓縮空氣從機組排出到儲氣罐、到前置過濾器、到乾燥機、再到後置過濾器,完成過濾和乾燥等淨化處理。
  • 有隔板/無隔板高效過濾器的區別
    常常會有用戶問到,有隔板高效過濾器和無隔板高效過濾器的區別是什麼?雖然他們的名字只相差一個字,有相似的工作原理,但是它們濾芯分隔物的材質、自身的特點與用途卻有很大不同,別著急,咱們一一來看。無隔板高效過濾器和有隔板高效過濾器的工作原理是一樣的,具體如下:慣性擴散和攔截原理空氣中有億萬個塵埃粒子,它們有時隨著氣流進行慣性運動,有時是沒有規則的運動,當塵埃粒子在運動和移動中撞到其它物體時就會粘到上面。
  • 資溪縣纖維轉盤過濾器哪家好廠家工作方法的區別
    資溪縣纖維轉盤過濾器哪家好廠家工作方法的區別 ,「qdvtuv2」   江蘇麥通環保專業生產纖維轉盤過濾器哪家好,設計堅固緊湊,使用壽命長,纖維轉盤過濾器哪家好過濾器效率高,處理量大;多重脫水。歡迎諮詢!
  • 流感和普通感冒到底有什麼區別?這次終於弄明白了!
    流感和普通感冒到底有什麼區別?這次終於弄明白了!有什麼區別?流感病毒按其核心蛋白分為四個型別:甲型(A型)、乙型(B型)、丙型(C型)和丁型(D型)。目前,甲型流感病毒的H1N1和H3N2亞型和乙型流感病毒共同循環引起流感的季節性流行。丙型流感病毒僅呈散發感染,丁型流感病毒主要感染牛且未發現人類感染。
  • 壓縮空氣過濾器生產廠家的責任和義務
    壓縮空氣過濾器是重要的淨化設備,一個專業的壓縮空氣過濾器生產廠家,可以幫助用戶帶來巨大的經濟效益。1.材質選擇壓縮空氣過濾器外部都是金屬結構,有的使用鋁合金,有的使用不鏽鋼,本質上區別不大;真正的材質區別在於濾芯,壓縮空氣過濾器的常用濾芯材質為濾紙濾芯、不鏽鋼濾芯、高分子材料濾芯。專業的壓縮空氣過濾器廠家,要根據用戶的過濾雜質及壓縮空氣參數來選擇不同的濾芯。
  • 用了這麼多年淨水器,終於知道超濾和反滲透淨水器的區別
    前置淨水器雖然只是一個粗過濾,但卻能過濾掉水中的泥沙、蟲卵、鐵屑等固體顆粒物質,是對門戶進水的第一道過濾,所以無論你後期選擇什麼樣的淨水器,一定要安裝前置過濾器。而淨水行業比較好的過濾器就是超濾淨水器和反滲透淨水器,但是這兩種淨水器還是有一定的區別的。
  • 美媒稱美國新反導戰略難實施:機載雷射攔截器仍是「夢想之物」
    參考消息網2月1日報導美國《華爾街日報》網站1月30日發表美國哈得孫研究所高級研究員亞瑟·赫爾曼的文章,題為《將飛彈防禦落實到地球上》,摘編如下:《飛彈防禦評估報告》顯示,在裡根總統公布「戰略防禦計劃」36年後,飛彈防禦終於成熟了
  • 裝個增壓泵和前置過濾器
    前置過濾器會不會是他用的電熱水器和淋浴龍頭有問題?肖先生請了熱水器和龍頭生產廠家的售後服務人員上門檢查,結果,兩家維修人員得出了一個相同的結論:產品沒問題,水壓有問題。原來,肖先生家所在的單元樓位於山坡之上,而他家又在該單元樓的頂樓,因此,冷水供應不足。不僅淋浴會出現忽冷忽熱的現象,平時使用冷水,也是時大時小。
  • (實用篇)淺談PHP攔截器之__set()與__get()的理解與使用方法
    但是,對屬性的讀取和賦值操作是非常頻繁的,因此在PHP5中,預定義了兩個函數「__get()」和「__set()」來獲取和賦值其屬性,以及檢查屬性的「__isset()」和刪除屬性的方法「__unset()」。
  • 驍龍835和660有啥區別?終於懂了!
    我們國產手機的處理器一致都採用的都是高通驍龍公司推出的兩款核心產品,驍龍8系列處理和驍龍6系列處理器。這兩款處理器從定位上有所不同8系列處理器的定位是頂級旗艦級,6系列的定位則是中高端機。在2017年兩款系列的處理器都推出了最新的版本836和660。
  • 陳醋,米醋,白醋,香醋同樣為醋,有啥區別?怎麼挑選?終於懂了
    陳醋,米醋,白醋,香醋同樣為醋,有啥區別?怎麼挑選?終於懂了說到醋的話大家都知道醋是一個不可或缺的調味品,我們在超市裡也能夠看到不同種類的醋,那麼這些醋的種類這麼多,他們到底有什麼樣的區別呢?該怎麼用呢?
  • 家裡有必要裝前置過濾器嗎?聽過來人良心勸告,終於搞懂了
    現在人們對於自己的生活品質是比較重視的,很多的朋友們,為了自己家人有一個好的生活環境,對於飲用水的安全問題也是比較重視的,有不少的朋友們會糾結家裡要不要安裝前置過濾器等家電產品。那麼家裡有必要裝前置過濾器嗎?聽過來人良心勸告,終於搞懂了!下面我們一起來了解一下吧。
  • 前置過濾器的優點和缺點
    相信有不少人在網上看到過前置過濾器的視頻,也有不少家庭安裝了前置過濾器,其實前置過濾器只能初步過濾。對於想要直接飲用的家庭來說,是存在不少缺點的,不過優點也不少。一起來看看前置過濾器的優點和缺點!前置過濾器的優點:前置過濾器濾芯不像其他濾芯一樣使用半年、一年就廢了,前置過濾可以定時拆洗,再進行重複利用的話,一般用個十年、二十年都是沒問題的。部分前置過濾器甚至帶有自動衝洗功能,你都不用手動去拆洗,它自己就定期衝洗完成了。
  • 智米推出智能馬桶蓋過濾器
    好在,近日小米生態鏈企業smartmi智米科技,正式發布了旗下的新款配件——智米智能馬桶蓋過濾器。這款產品售價僅為99元,將於6月24日正式上架小米有品平臺,並於隨後登陸智米體驗店北京頤堤港店,這次終於不用跑日本了。
  • Google限制廣告攔截器使用的Chrome功能
    毫不奇怪,此舉激怒了那些製造廣告攔截器的人。uBlock Origin的開發者雷蒙德·希爾(Raymond Hill)在論壇上聲稱,谷歌的真正意圖是投放更多廣告。其他人則說他們計劃放棄Chrome。「這是Google的一個令人失望的決定。