目錄
- Spring Boot 過濾器
- 1.什么是過濾器
- 2.工作機制
- 3.實現過濾器
- Spring Boot 攔截器
- 1. 什么是攔截器
- 2. 工作原理
- 3.實現
- 4.拓展(MethodInterceptor 攔截器)
- 實現
- 過濾器和攔截器區別
- 過濾器和攔截器應用場景
- 過濾器
- 攔截器
Spring Boot 過濾器
1.什么是過濾器
-
過濾器(Filter),是 Servlet 規范規定的,在 Servlet 前執行的。用于攔截和處理 HTTP 請求和響應,可用于身份認證、授權、日志記錄和設置字符集(CharacterEncodingFilter)等場景。
-
過濾器位于整個請求處理流程的最前端,因此在請求到達 Controller 層前,都會先被過濾器處理。
-
過濾器可以攔截多個請求或響應,一個請求或響應也可以被多個過濾器攔截。
2.工作機制
Filter 的生命周期對應的三個關鍵方法:
方法 | 作用 |
---|---|
init() | 當請求發起是,會調用init()方法初始化Filter實例,僅初始化一次 ,若設置初始化參數時可調用該方法 |
doFilter() | 攔截要執行的請求,對請求和響應進行處理 |
destroy() | 請求結束時調用該方法銷毀Filter的實例 |
3.實現過濾器
- 實現 Filter 接口
@WebFilter(urlPatterns = "/*")
public class MyFilter implements Filter {@Overridepublic void init(FilterConfig filterConfig) throws ServletException {// 用于完成 Filter 的初始化Filter.super.init(filterConfig);}@Overridepublic void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {System.out.println("過濾器已經攔截成功!!!");// 執行該方法之前,即對用戶請求進行預處理;執行該方法之后,即對服務器響應進行后處理。chain.doFilter(request,response);}@Overridepublic void destroy() {// 用于 Filter 銷毀前,完成某些資源的回收;Filter.super.destroy();}
}
- 啟動類添加注解 @ServletComponentScan
- 通過@Component和@Order(1)注解可以保證過濾器執行順序
Spring Boot 攔截器
1. 什么是攔截器
依賴于web框架,在SpringMVC中就是依賴于SpringMVC框架。在實現上基于Java的反射機制,屬于面向切面編程(AOP)的一種運用。由于攔截器是基于web框架的調用,因此可以使用Spring的依賴注入(DI)進行一些業務操作,同時一個攔截器實例在一個controller生命周期之內可以多次調用。但是缺點是只能對controller請求進行攔截,對其他的一些比如直接訪問靜態資源的請求則沒辦法進行攔截處理。
2. 工作原理
SpringMVC的機制是由同一個Servlet來分發請求給不同的Controller,其實這一步是在Servlet的service()方法中執行的。所以過濾器、攔截器、service()方法,dispatc()方法的執行順序應該是這樣的
3.實現
配置攔截器,實現WebMvcConfigurer接口,加@Configuration注解并重寫addInterceptors方法。
@Configuration
public class MyWebConfigurer implements WebMvcConfigurer {@Resourceprivate MyHandlerInterceptor myHandlerInterceptor;@Overridepublic void addInterceptors(InterceptorRegistry registry) {List<String> patterns = new ArrayList<>();patterns.add("/test/handlerInterceptor");registry.addInterceptor(myHandlerInterceptor).addPathPatterns(patterns) // 需要攔截的請求.excludePathPatterns(); // 不需要攔截的請求}
}
4.拓展(MethodInterceptor 攔截器)
-
MethodInterceptor 是 AOP 中的攔截器,它攔截的目標是方法,可以不是 Controller 中的方法。
-
在對一些普通的方法上的攔截可以使用該攔截器,這是 HandlerInterceptor 無法實現的。
-
可用來進行方法級別的身份認證、授權以及日志記錄等,也可基于自定義注解實現一些通用的方法增強功能。
實現
MethodInterceptor 是基于 AOP 實現的,所以根據不同的代理有多種實現方式。
- 創建 Interceptor 類,實現MethodInterceptor接口,重寫invoke方法,加@Component注解。
@Component
public class MyMethodInterceptor implements MethodInterceptor {@Overridepublic Object invoke(MethodInvocation invocation) throws Throwable {System.out.println("進入攔截,方法執行前,攔截方法是:" + invocation.getMethod().getName());Object result = invocation.proceed();System.out.println("方法執行后");return result;}}
- 配置自動代理,加@Configuration注解并創建自動代理BeanNameAutoProxyCreator。
@Configuration
public class MyMethodConfigurer {@Resourceprivate MyMethodInterceptor myMethodInterceptor;@Beanpublic BeanNameAutoProxyCreator beanNameAutoProxyCreator() {// 使用BeanNameAutoProxyCreator來創建代理BeanNameAutoProxyCreator beanNameAutoProxyCreator = new BeanNameAutoProxyCreator();// 指定一組需要自動代理的Bean名稱,Bean名稱可以使用*通配符beanNameAutoProxyCreator.setBeanNames("user*");//設置攔截器名稱,這些攔截器是有先后順序的beanNameAutoProxyCreator.setInterceptorNames("myMethodInterceptor");return beanNameAutoProxyCreator;}}
過濾器和攔截器區別
-
過濾器是基于函數回調,攔截器是基于java的反射機制的。
-
過濾器是servlet規范規定的,只能用于web程序中,而攔截器是在spring容器中,它不依賴servlet容器。
-
過濾器可以攔截幾乎所有的請求(包含對靜態資源的請求),而攔截器只攔截action請求(不攔截靜態資源請求)。
-
過濾器不能訪問action上下文、值棧里的對象,攔截器可以訪問action上下文、值棧里的對象。
-
在action的生命周期中,過濾器只能在容器初始化時被調用一次,攔截器可以多次被調用,而。
-
攔截器可以獲取IOC容器中的各個bean,而過濾器就不行,這點很重要,在攔截器里注入一個service,可以調用業務邏輯。
-
攔截器是被包裹在過濾器之中。
過濾器(Filter) :可以拿到原始的http請求,但是拿不到你請求的控制器和請求控制器中的方法的信息。
攔截器(Interceptor):可以拿到你請求的控制器和方法,卻拿不到請求方法的參數。
切片(Aspect): 可以拿到方法的參數,但是卻拿不到http請求和響應的對象
過濾器和攔截器應用場景
過濾器
- 過濾敏感詞匯(防止sql注入)
- 設置字符編碼
- URL級別的權限訪問控制
- 壓縮響應信息
攔截器
- 登錄驗證,判斷用戶是否登錄。
- 權限驗證,判斷用戶是否有權限訪問資源,如校驗token
- 日志記錄,記錄請求操作日志(用戶ip,訪問時間等),以便統計請求訪問量。
- 處理cookie、本地化、國際化、主題等。
- 性能監控,監控請求處理時長等。
- 通用行為:讀取cookie得到用戶信息并將用戶對象放入請求,從而方便后續流程使用,還有如提取Locale、Theme信息等,只要是多個處理器都需要的即可使用攔截器實現)