這個是不久前在面試的時候遇到的一個問題,當時直接懵了,兩個單拎出來,雖然不太完全,但都大概知道可以對請求進行攔截,放在一起比較,可真是頭疼。
其實之前面試完就去學習了一波,只不過那個時候沒及時總結,現在總結一下,以免日後遇到這類問題又給忘咯。
要理解這類問題,光靠死記硬背可能當時有用,過一陣子就差不多忘了。要想真的牢記,我們必須要實操一下。
Filter的使用
首先,要使用Filter,必須實現javax.servlet.Filter接口:
init和destroy是default方法,實現類可以不用實現。doFilter必須實現,也就是說,作為一個過濾器,doFilter必須要定義。doFlilter方法中傳進來的FilterChain對象用來調用下一個過濾器。攔截器的使用
過濾器與攔截器到底有啥區別呢?
一、實現原理不同
過濾器的實現基於回調函數攔截器基於Java的反射機制【動態代理】實現。二、使用範圍不同
過濾器是Servlet的規範,需要實現javax.servlet.Filter接口,Filter使用需要依賴於Tomcat等容器。攔截器是Spring組件,定義在org.springframework.web.servlet包下,由Spring容器管理【又有更加豐富的生繆那個周期處理方法,細粒度,且能夠使用Spring中的資源】,不依賴Tomcat等容器。三、觸發時機不同
這一段在HandlerInterceptor類的注釋上可以發現,兩者的觸發時機是不同的:
過濾器:對請求在進入後Servlet之前或之後進行處理。攔截器:對請求在handler【Controller】前後進行處理。
四、執行順序不同
同時配置了過濾器和攔截器的情形:
過濾器的順序每一次都將chain對象傳入,達到最後接口回調的效果:
攔截器的順序preHandle1 -> preHande2 -> 【Controller】 -> postHandle2 -> postHandle1 -> afterCompletion2 -> afterComplention1
preHandle按照註冊順序,後兩個與註冊順序相反。
一個攔截器的preHandle為false,則之後的所有攔截器都不會執行。一個攔截器的preHandle為true,則這個攔截器的triggerAfterCompletion一定會執行。只有所有的攔截器preHandler都為true,也就是正常執行,postHandle才會執行。
五、控制執行順序方式不同
兩者默認都是使用註冊順序,如果想要認為控制執行的順序,方式略有不同:
過濾器如果想要強制改變,可以使用@Order註解。攔截器如果使用order()方法
總結