新聞中心
前言
小伙伴們應該聽說過過濾器、攔截器、切面,印象上都能夠起到截斷攔截的作用,在做一些業(yè)務需求時,不知道如何選擇,今天老顧就來介紹一下他們之間的區(qū)別。

成都創(chuàng)新互聯(lián)是一家專注于做網(wǎng)站、網(wǎng)站建設與策劃設計,塔城網(wǎng)站建設哪家好?成都創(chuàng)新互聯(lián)做網(wǎng)站,專注于網(wǎng)站建設10年,網(wǎng)設計領域的專業(yè)建站公司;建站業(yè)務涵蓋:塔城等地區(qū)。塔城做網(wǎng)站價格咨詢:028-86922220
Filter過濾器
過濾器可以攔截到方法的請求和響應(ServletRequest request, ServletResponse response),并對請求響應做出過濾操作。
過濾器依賴于servlet容器。在實現(xiàn)上,基于函數(shù)回調(diào),它可以對幾乎所有請求進行過濾,一個過濾器實例只能在容器初始化時調(diào)用一次。
使用過濾器的目的是用來做一些過濾操作,獲取我們想要獲取的數(shù)據(jù),比如:在過濾器中修改字符編碼;在過濾器中修改HttpServletRequest的一些參數(shù),包括:過濾低俗文字、危險字符等。
話不多說,先上代碼
再定義兩個Controller,一個UserController,一個OrderController
雖然Filter過濾器和Controller請求都已經(jīng)定義了,但現(xiàn)在過濾器是不起作用的。需要把Filter配置一下,有兩個方案
第一個方案在Filter上面加上@Component
- @Component
- public class TimeFilter implements Filter
第二個方案配置化注冊過濾器
第二個方案的特點就是可以細化到過濾哪些規(guī)則的URL
我們來啟動應用時,過濾器被初始化了,init函數(shù)被回調(diào)。
請求http://localhost:9000/order/1
看看控制臺的日志輸出
請求http://localhost:9000/user/1
控制臺日志輸出
停止應用后,控制臺輸出
Filter隨web應用的啟動而啟動,只初始化一次,隨web應用的停止而銷毀。
1.啟動服務器時加載過濾器的實例,并調(diào)用init()方法來初始化實例;
2.每一次請求時都只調(diào)用方法doFilter()進行處理;
3.停止服務器時調(diào)用destroy()方法,銷毀實例。
我們再來看看doFilter方法
doFilter(ServletRequest request, ServletResponse response, FilterChain chain)
從參數(shù)我們看到,filter里面是能夠獲取到請求的參數(shù)和響應的數(shù)據(jù);但此方法是無法知道是哪一個Controller類中的哪個方法被執(zhí)行。
還有一點需要注意的是,filter中是沒法使用注入的bean的,也就是無法使用@Autowired
上面代碼注入的值為null。這是為什么呢?
其實Spring中,web應用啟動的順序是:listener->filter->servlet,先初始化listener,然后再來就filter的初始化,再接著才到我們的dispathServlet的初始化,因此,當我們需要在filter里注入一個注解的bean時,就會注入失敗,因為filter初始化時,注解的bean還沒初始化,沒法注入。
如果一定你要使用,需要做一些處理,可以私信老顧哦
Interceptor攔截器
依賴于web框架,在SpringMVC中就是依賴于SpringMVC框架。在實現(xiàn)上,基于Java的反射機制,屬于面向切面編程(AOP)的一種運用,就是在一個方法前,調(diào)用一個方法,或者在方法后,調(diào)用一個方法。
在WebMvcConfigurationSupport配置一下
執(zhí)行結(jié)果
我們發(fā)現(xiàn)攔截器中可以獲取到Controller對象
preHandle(HttpServletRequest request, HttpServletResponse response, Object handler)
object handler就是controller方法對象
HandlerMethod handlerMethod = (HandlerMethod)handler;
handlerMethod.getBean().getClass().getName(); //獲取類名
handlerMethod.getMethod().getName(); //獲取方法名
但我們發(fā)現(xiàn)獲取不到方法的參數(shù)值,這個是為什么呢?在DispatcherServlet類中,方法
doDispatch(HttpServletRequest request, HttpServletResponse response)
applyPreHandle這個方法執(zhí)行,就是執(zhí)行的攔截器的preHandler方法,但這個過程中,controller方法沒有從request中獲取請求參數(shù),組裝方法參數(shù);而是在ha.handle這個方法的時候,才會組裝參數(shù)
雖然沒法得到方法的參數(shù),但是可以獲得IOC的bean哦。
再說明一點的是postHandler方法
postHandler方法的執(zhí)行,當controller內(nèi)部有異常,posthandler方法是不會執(zhí)行的。
afterCompletion方法,不管controller內(nèi)部是否有異常,都會執(zhí)行此方法;此方法還會有個Exception ex這個參數(shù);如果有異常,ex會有異常值;沒有異常 此值為null
注意點如果controller內(nèi)部有異常,但異常被@ControllerAdvice 異常統(tǒng)一捕獲的話,ex也會為null
Aspect切片
AOP操作可以對操作進行橫向的攔截,最大的優(yōu)勢在于他可以獲取執(zhí)行方法的參數(shù),對方法進行統(tǒng)一的處理。常見使用日志,事務,請求參數(shù)安全驗證等
上面的代碼中,我們是可以獲取方法的參數(shù)的
雖然切面aop可以拿到方法參數(shù),但拿不到response,request對象。
總結(jié)
我們這里來總結(jié)一下過濾器、攔截器、Aspect,看看區(qū)別
如果三者方式同時采用,那他們的執(zhí)行順序是什么呢?
filter -> interceptor -> ControllerAdvice -> aspect -> controller
返回值順序,或異常返回順序
controller -> aspect -> controllerAdvice -> Interceptor -> Filter
用一個圖描述一下執(zhí)行順序
小伙伴們可以根據(jù)自身業(yè)務,和上面技術的各自特點,去選擇相應的技術。今天老顧就介紹到這里,謝謝?。。?/p>
當前題目:filter、interceptor、aspect應如何選擇?很多人中招
本文路徑:http://www.5511xx.com/article/cojddsh.html


咨詢
建站咨詢
