Spring攔截器之HandlerInterceptor使用方式
概述
有時(shí)候我們需要進(jìn)行一些預(yù)處理和后處理,或者是攔截請(qǐng)求,在請(qǐng)求前后后做一些處理
使用Spring MVC框架,那么建議使用HandlerInterceptor,它可以類(lèi)似于普通bean直接注冊(cè)到Spring容器中被管理
HandlerInterceptor的三個(gè)抽象方法
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
在執(zhí)行Handler之前(執(zhí)行業(yè)務(wù)邏輯之前),根據(jù)攔截器鏈順序執(zhí)行
- 每個(gè)
Interceptor的調(diào)用會(huì)依據(jù)它的聲明順序依次執(zhí)行,而且最先執(zhí)行的都是Interceptor 中的preHandle 方法 - 所以可以在這個(gè)方法中進(jìn)行一些前置初始化操作或者是對(duì)當(dāng)前請(qǐng)求的一個(gè)預(yù)處理
- 也可以在這個(gè)方法中進(jìn)行一些判斷來(lái)決定請(qǐng)求是否要繼續(xù)進(jìn)行下去
該方法的返回值是布爾值Boolean 類(lèi)型的,
- 當(dāng)它返回為false 時(shí),表示請(qǐng)求結(jié)束,后續(xù)的Interceptor 和Controller 都不會(huì)再執(zhí)行;
- 當(dāng)返回值為true 時(shí)就會(huì)繼續(xù)調(diào)用下一個(gè)Interceptor 的preHandle 方法,如果已經(jīng)是最后一個(gè)Interceptor 的時(shí)候就會(huì)是調(diào)用當(dāng)前請(qǐng)求的Controller 方法。
postHandle
在執(zhí)行Handler成功(執(zhí)行業(yè)務(wù)邏輯成功)之后,根據(jù)攔截器鏈倒序執(zhí)行,如果前面的流程中拋出異?;蛘哒?qǐng)求被攔截則不會(huì)執(zhí)行!
- 在當(dāng)前所屬的Interceptor 的preHandle 方法的返回值為true 時(shí)才能被調(diào)用
- 在當(dāng)前請(qǐng)求進(jìn)行處理之后,也就是Controller 方法調(diào)用之后執(zhí)行,但是它會(huì)在DispatcherServlet 進(jìn)行視圖返回渲染之前被調(diào)用,
- 所以我們可以在這個(gè)方法中對(duì)Controller 處理之后的ModelAndView 對(duì)象進(jìn)行操作
- postHandle 方法被調(diào)用的方向跟preHandle 是相反的,也就是說(shuō)先聲明的Interceptor 的postHandle 方法反而會(huì)后執(zhí)行
afterCompletion
在請(qǐng)求處理完畢之后執(zhí)行,無(wú)論是否有響應(yīng)視圖,無(wú)論有沒(méi)有通過(guò)preHandle,無(wú)論有沒(méi)有拋出異常。
只會(huì)對(duì)此前放行成功(preHandle返回true)的攔截器進(jìn)行倒序調(diào)用。
- 在當(dāng)前所屬的Interceptor 的preHandle 方法的返回值為true 時(shí)才能被調(diào)用
- 該方法將在整個(gè)請(qǐng)求結(jié)束之后,也就是在DispatcherServlet 渲染了對(duì)應(yīng)的視圖之后執(zhí)行。
- 這個(gè)方法的主要作用是用于進(jìn)行資源清理工作的
使用
構(gòu)建攔截器(HandlerInterceptor )
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.core.context.SecurityContext;
import org.springframework.stereotype.Component;
import org.springframework.web.servlet.HandlerInterceptor;
import org.springframework.web.servlet.ModelAndView;
import com.gildata.gup.domain.User;
import com.gildata.gup.domain.UserEncryptReset;
import com.gildata.gup.repository.UserEncryptResetRepository;
@Component // 不可少
public class xxxStateInterceptor implements HandlerInterceptor { // 必須實(shí)現(xiàn)HandlerInterceptor接口
@Override
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler)
throws Exception {
// TODO Auto-generated method stub
// ....
return true;
}
@Override
public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler,
ModelAndView modelAndView) throws Exception {
// TODO Auto-generated method stub
return;
}
@Override
public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex)
throws Exception {
// TODO Auto-generated method stub
}
}注冊(cè)攔截器(WebMvcConfigurerAdapter )
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.servlet.config.annotation.InterceptorRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurerAdapter;
import com.gildata.gup.interceptor.PasswordStateInterceptor;
@Configuration // 配置
public class WebConfigfilter extends WebMvcConfigurerAdapter{
@Autowired
private XxxStateInterceptor xxxStateInterceptor ; // 實(shí)例化攔截器
@Override
public void addInterceptors(InterceptorRegistry registry) {
// super.addInterceptors(registry);
// 注冊(cè)自定義的攔截器passwordStateInterceptor
registry.addInterceptor(xxxStateInterceptor)
.addPathPatterns("/api/*") //匹配要過(guò)濾的路徑
.excludePathPatterns("/api/changeUser/*") //匹配不過(guò)濾的路徑。/api/changeUser后面的所有接口不能攔截
.excludePathPatterns("/api/getAge", "/api/getName") // /api/getAge也不能攔截,/api/getName這個(gè)接口的請(qǐng)求不能攔截
}
}兩個(gè)常用方法:
.addPathPatterns():增加url的攔截路徑,“/**”意思是所有請(qǐng)求都要攔截;.excludePathPatterns():排除url的攔截路徑,如:“/api/getAge”, “/api/getName”:意為這兩個(gè)接口不做攔截;
注意
springBoot2.0以上 WebMvcConfigurerAdapter 方法過(guò)時(shí),有兩種替代方案:
- 繼承 WebMvcConfigurationSupport 類(lèi);
- 實(shí)現(xiàn) WebMvcConfigurer 接口;
但是,繼承WebMvcConfigurationSupport會(huì)讓Spring-boot對(duì)mvc的自動(dòng)配置失效,所以 建議用實(shí)現(xiàn)WebMvcConfigurer接口的方式 。
所以上面的注冊(cè)攔截器更改為:
@Configuration // 配置
public class WebConfigfilter implements WebMvcConfigurer{
@Autowired
private XxxStateInterceptor xxxStateInterceptor ; // 實(shí)例化攔截器
@Override
public void addInterceptors(InterceptorRegistry registry) {
// super.addInterceptors(registry);
// 注冊(cè)自定義的攔截器passwordStateInterceptor
registry.addInterceptor(xxxStateInterceptor)
.addPathPatterns("/api/*") //匹配要過(guò)濾的路徑
.excludePathPatterns("/api/changeUser/*") //匹配不過(guò)濾的路徑。/api/changeUser后面的所有接口不能攔截
.excludePathPatterns("/api/getAge", "/api/getName") // /api/getAge也不能攔截,/api/getName這個(gè)接口的請(qǐng)求不能攔截
}
}總結(jié)
以上為個(gè)人經(jīng)驗(yàn),希望能給大家一個(gè)參考,也希望大家多多支持腳本之家。
- 深入解析Spring MVC中攔截器Interceptor的實(shí)現(xiàn)原理和應(yīng)用場(chǎng)景
- Spring?Boot?Interceptor的原理、配置、順序控制及與Filter的關(guān)鍵區(qū)別對(duì)比分析
- SpringBoot使用Mybatis-Plus中分頁(yè)插件PaginationInterceptor詳解
- Spring Boot攔截器Interceptor與過(guò)濾器Filter深度解析(區(qū)別、實(shí)現(xiàn)與實(shí)戰(zhàn)指南)
- Spring Mvc中攔截器Interceptor用法解讀
- Spring Boot攔截器Interceptor與過(guò)濾器Filter詳細(xì)教程(示例詳解)
- Spring的攔截器HandlerInterceptor詳解
- SpringMVC的處理器攔截器HandlerInterceptor詳解
- spring中Interceptor的使用小結(jié)
相關(guān)文章
SpringBoot實(shí)現(xiàn)圖片防盜鏈的五種方式詳解
出于安全考慮,我們需要后端返回的圖片只允許在某個(gè)網(wǎng)站內(nèi)展示,不想被爬蟲(chóng)拿到圖片地址后被下載,或者,不想瀏覽器直接訪(fǎng)問(wèn)圖片鏈接,出于性能考慮,不想要?jiǎng)e人的網(wǎng)站,拿著我們的圖片鏈接去展示,所以本文給大家介紹了SpringBoot實(shí)現(xiàn)圖片防盜鏈的五種方式2025-08-08
使用Spring Security控制會(huì)話(huà)的方法
在本文中,我們將說(shuō)明Spring Security如何允許我們控制HTTP會(huì)話(huà)。這篇文章主要介紹了使用Spring Security控制會(huì)話(huà) ,需要的朋友可以參考下2019-05-05
淺談springboot @Repository與@Mapper的區(qū)別
本文主要介紹了淺談springboot @Repository與@Mapper的區(qū)別,文中通過(guò)示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2022-03-03
IDEA+Maven搭建JavaWeb項(xiàng)目的方法步驟
本文主要介紹了IDEA+Maven搭建JavaWeb項(xiàng)目的方法步驟,文中通過(guò)示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2021-11-11
Java Spring 中 @PostConstruct 注解使用原理及常見(jiàn)場(chǎng)景
在 Java Spring 中,@PostConstruct 注解是一個(gè)非常實(shí)用的功能,它允許開(kāi)發(fā)者在 Spring 容器完全初始化 Bean 后執(zhí)行某些操作,本文將詳細(xì)介紹 @PostConstruct 注解的使用,包括其原理、常見(jiàn)場(chǎng)景和代碼示例,2025-04-04
Java 按照字節(jié)來(lái)截取字符串的代碼(不會(huì)出現(xiàn)半個(gè)漢字)
Java 按照字節(jié)來(lái)截取字符串的工具,不會(huì)出現(xiàn)半個(gè)漢字。一個(gè)中文兩個(gè)字節(jié),一個(gè)英文字符只占 1 個(gè)字節(jié)** 1. 通常我們用于前端顯示的時(shí)候,防止標(biāo)題過(guò)長(zhǎng)2014-01-01
java面試常問(wèn)的Runnable和Callable的區(qū)別
大家好,本篇文章主要講的是java面試常問(wèn)的Runnable和Callable的區(qū)別,感興趣的同學(xué)趕快來(lái)看一看吧,對(duì)你有幫助的話(huà)記得收藏一下2022-01-01

