Spring的攔截器HandlerInterceptor詳解
1 什么是攔截器
攔截器是相對于Spring中來說的,它和過濾器不一樣,過濾器的范圍更廣一些是相對于Tomcat容器來說的。攔截器可以對用戶進(jìn)行攔截過濾處理。
但是并不是說攔截器只對請求進(jìn)入Controller控制器之前起作用,它也分為3個部分:
- 請求進(jìn)入Controller之前,通過攔截器執(zhí)行代碼邏輯
- Controller執(zhí)行之后(只是Controller執(zhí)行完畢,視圖還沒有開始渲染),通過攔截器執(zhí)行代碼邏輯
- Controller完全執(zhí)行完畢(整個請求全部結(jié)束),通過攔截器執(zhí)行代碼邏輯
2HandlerInterceptor和WebMvcConfigurer
想要自己配置一個攔截器,就必須用到HandlerInterceptor和WebMvcConfigurer這兩個接口。
2.1HandlerInterceptor
作用:自定義攔截器
如何創(chuàng)建:這個接口我們通常會自定義一個類。加上@Component注解,并且使它實現(xiàn)HandlerInterceptor接口(根據(jù)需求重寫里面的三個方法)
HandlerInterceptor源碼如下:
public interface HandlerInterceptor {
default boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
return true;
}
default void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, @Nullable ModelAndView modelAndView) throws Exception {
}
default void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, @Nullable Exception ex) throws Exception {
}
}- preHandle:此方法的作用是在請求進(jìn)入到Controller進(jìn)行攔截,有返回值。(返回true則將請求放行進(jìn)入Controller控制層,false則請求結(jié)束返回錯誤信息)
用法:登錄驗證(判斷用戶是否登錄)權(quán)限驗證:判斷用戶是否有權(quán)訪問資源(校驗token)
- postHandle:該方法是在Controller控制器執(zhí)行完成但是還沒有返回模板進(jìn)行渲染攔截。沒有返回值。就是Controller----->攔截------>ModelAndView。
用法:因此我們可以將Controller層返回來的參數(shù)進(jìn)行一些修改,它就包含在ModelAndView中,所以該方法多了一個ModelAndView參數(shù)。
- afterCompletion:該方法是在ModelAndView返回給前端渲染后執(zhí)行。
用法:例如登錄的時候,我們經(jīng)常把用戶信息放到ThreadLocal中,為了防止內(nèi)存泄漏,就需要將其remove掉,該操作就是在這里執(zhí)行的。
2.2WebMvcConfigurer
作用:添加攔截規(guī)則
如何創(chuàng)建:自定義一個類,實現(xiàn)WebMvcConfigurer并將它注入到Spring容器中。根據(jù)需求實現(xiàn)里面方法。
WebMvcConfigurer源碼如下:
public interface WebMvcConfigurer {
default void configurePathMatch(PathMatchConfigurer configurer) {
}
default void configureContentNegotiation(ContentNegotiationConfigurer configurer) {
}
default void configureAsyncSupport(AsyncSupportConfigurer configurer) {
}
default void configureDefaultServletHandling(DefaultServletHandlerConfigurer configurer) {
}
default void addFormatters(FormatterRegistry registry) {
}
default void addInterceptors(InterceptorRegistry registry) {
}
default void addResourceHandlers(ResourceHandlerRegistry registry) {
}
default void addCorsMappings(CorsRegistry registry) {
}
default void addViewControllers(ViewControllerRegistry registry) {
}
default void configureViewResolvers(ViewResolverRegistry registry) {
}
default void addArgumentResolvers(List<HandlerMethodArgumentResolver> resolvers) {
}
default void addReturnValueHandlers(List<HandlerMethodReturnValueHandler> handlers) {
}
default void configureMessageConverters(List<HttpMessageConverter<?>> converters) {
}
default void extendMessageConverters(List<HttpMessageConverter<?>> converters) {
}
default void configureHandlerExceptionResolvers(List<HandlerExceptionResolver> resolvers) {
}
default void extendHandlerExceptionResolvers(List<HandlerExceptionResolver> resolvers) {
}
@Nullable
default Validator getValidator() {
return null;
}
@Nullable
default MessageCodesResolver getMessageCodesResolver() {
return null;
}
}根據(jù)源碼發(fā)現(xiàn),這里面有很多方法,但是通常我們只用到了里面的兩種方法如下:
addInterceptors:添加攔截器,攔截器需要攔截的路徑和需要排除攔截的路徑都需要在其中配置
addResourceHandlers:配置靜態(tài)資源路徑,即某些請求需要讀取某個路徑下的靜態(tài)資源內(nèi)容,需要配置該靜態(tài)資源的路徑,通過該方法可以統(tǒng)一給這些請求配置指定靜態(tài)資源路徑
3 攔截器實現(xiàn)流程
根據(jù)第二部分,我們知道了配置攔截器的準(zhǔn)備工作。
1)自定義類實現(xiàn)HandlerInterceptor
@Component
public class HeaderInterceptor implements HandlerInterceptor {
@Override
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
System.out.println("進(jìn)入攔截器=======執(zhí)行前========");
return true;
}
@Override
public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception {
System.out.println("進(jìn)入攔截器=======執(zhí)行中========");
}
@Override
public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception {
System.out.println("進(jìn)入攔截器=======執(zhí)行后========");
}
}2)自定義類實現(xiàn)WebMvcConfigurer
package com.liubujun.springbootinterceptor.config;
import com.liubujun.springbootinterceptor.interceptor.HeaderInterceptor;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.servlet.config.annotation.InterceptorRegistry;
import org.springframework.web.servlet.config.annotation.ResourceHandlerRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurationSupport;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;
import javax.annotation.Resource;
import java.util.ArrayList;
import java.util.List;
/**
* @Author: liubujun
* @Date: 2022/10/10 19:55
*/
/**
* 此處也可以繼承WebMvcConfigurationSupport
*/
@Configuration
public class WebAppConfig implements WebMvcConfigurer {
@Resource
private HeaderInterceptor headerInterceptor;
/**
* 添加攔截規(guī)則
* @param registry
*/
@Override
public void addInterceptors(InterceptorRegistry registry) {
List<String> patterns = new ArrayList<>();
patterns.add("/login/login");
registry.addInterceptor(headerInterceptor)
.addPathPatterns("/**") //所有的請求都要攔截。
.excludePathPatterns(patterns); //將不需要攔截的接口請求排除在外
}
/**
* //下面代碼意思是:配置一個攔截器,如果訪問路徑時addResourceHandler中的這個路徑(我這里是/**表示所有的路徑),
* 那么就映射到訪問本地的addResourceLocations這個路徑上,這樣就可以看到該路徑上的資源了
* @param registry
*/
@Override
public void addResourceHandlers(ResourceHandlerRegistry registry) {
registry.addResourceHandler("/**") //配置需要添加靜態(tài)資源請求的url
.addResourceLocations("classpath:/pic/"); //配置靜態(tài)資源路徑
}
}3)測試類
@RestController
public class LoginController {
@GetMapping("/login/login")
public String testLoginInterceptor(){
return "登錄請求沒有被攔截====》看控制臺沒有輸出";
}
@GetMapping("/test/other")
public String testOtherInterceptor(){
return "該請求沒有被攔截,看控制臺有輸出";
}
}4)本地添加靜態(tài)資源

猜驗證1:
由于在配置攔截規(guī)則中,攔截了所有請求,但是排除了登錄請求,所以
/login/login 請求正常訪問,但不會進(jìn)入攔截器,故控制臺不會打印攔截器中的輸出語句。


驗證2:
由于在配置攔截規(guī)則
由于在配置攔截規(guī)則中,攔截了所有請求,但是排除了登錄請求,所以
/test/other請求正常訪問,會進(jìn)入攔截器,控制臺會打印攔截器中的輸出語句。


驗證3:攔截器中配置了映射靜態(tài)資源路徑,所以可以訪問到自己上傳到本地服務(wù)器的圖片。

到此這篇關(guān)于Spring的攔截器HandlerInterceptor詳解的文章就介紹到這了,更多相關(guān)HandlerInterceptor攔截器內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
- 深入解析Spring MVC中攔截器Interceptor的實現(xiàn)原理和應(yīng)用場景
- Spring?Boot?Interceptor的原理、配置、順序控制及與Filter的關(guān)鍵區(qū)別對比分析
- SpringBoot使用Mybatis-Plus中分頁插件PaginationInterceptor詳解
- Spring Boot攔截器Interceptor與過濾器Filter深度解析(區(qū)別、實現(xiàn)與實戰(zhàn)指南)
- Spring Mvc中攔截器Interceptor用法解讀
- Spring Boot攔截器Interceptor與過濾器Filter詳細(xì)教程(示例詳解)
- Spring攔截器之HandlerInterceptor使用方式
- SpringMVC的處理器攔截器HandlerInterceptor詳解
- spring中Interceptor的使用小結(jié)
相關(guān)文章
SpringBoot整合mybatisPlus實現(xiàn)批量插入并獲取ID詳解
這篇文章主要為大家詳細(xì)介紹了SpringBoot如何整合mybatisPlus實現(xiàn)批量插入并獲取ID,文中的示例代碼講解詳細(xì),感興趣的小伙伴可以跟隨小編一起學(xué)習(xí)一下2025-04-04
Java中Integer的parseInt和valueOf的區(qū)別詳解
這篇文章主要介紹了Java中Integer的parseInt和valueOf的區(qū)別詳解,nteger.parseInt(s)是把字符串解析成int基本類型,Integer.valueOf(s)是把字符串解析成Integer對象類型,其實int就是Integer解包裝,Integer就是int的包裝,需要的朋友可以參考下2023-11-11
利用Jackson實現(xiàn)JSON數(shù)據(jù)的合并
Jackson的功能豐富,安全可靠并且具有比較好的兼容性,這讓程序開發(fā)人員可以很方便地實現(xiàn)JSON 數(shù)據(jù)的相互轉(zhuǎn)換,下面小編就來和大家介紹一下如何利用Jackson實現(xiàn)JSON數(shù)據(jù)的合并吧2025-03-03
SpringBoot+SpringCloud用戶信息微服務(wù)傳遞實現(xiàn)解析
這篇文章主要介紹了SpringBoot+SpringCloud實現(xiàn)登錄用戶信息在微服務(wù)之間的傳遞,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友可以參考下2019-11-11
使用dubbo+zookeeper+spring boot構(gòu)建服務(wù)的方法詳解
這篇文章主要給大家介紹了關(guān)于如何使用dubbo+zookeeper+spring boot構(gòu)建服務(wù)的相關(guān)資料,文中通過示例代碼及圖片介紹的非常詳細(xì),需要的朋友可以參考借鑒,下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧2018-05-05
Java中@ConditionalOnProperty注解使用
在Spring?Boot中,@ConditionalOnProperty注解是一種方便的工具,用于根據(jù)應(yīng)用程序配置文件中的屬性值來控制Bean的創(chuàng)建和加載,本文就來介紹一下Java中@ConditionalOnProperty注解使用,感興趣的可以了解一下2023-11-11

