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)文章
Java實(shí)現(xiàn)順時(shí)針輸出螺旋二維數(shù)組的方法示例
這篇文章主要介紹了利用Java如何實(shí)現(xiàn)順時(shí)針輸出螺旋二維數(shù)組的方法示例,文中給出了詳細(xì)的示例代碼和注釋?zhuān)嘈艑?duì)大家具有一定的參考價(jià)值,有需要的朋友們下面來(lái)一起看看吧。2017-02-02
一小時(shí)迅速入門(mén)Mybatis之實(shí)體類(lèi)別名與多參數(shù) 動(dòng)態(tài)SQL
這篇文章主要介紹了一小時(shí)迅速入門(mén)Mybatis之實(shí)體類(lèi)別名與多參數(shù) 動(dòng)態(tài)SQL,本文給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下2021-09-09
Java微服務(wù)開(kāi)發(fā)之Swagger詳解
Swagger 是一個(gè)規(guī)范和完整的框架,用于生成、描述、調(diào)用和可視化 RESTful 風(fēng)格的 Web 服務(wù)??傮w目標(biāo)是使客戶端和文件系統(tǒng)作為服務(wù)器以同樣的速度來(lái)更新。文件的方法,參數(shù)和模型緊密集成到服務(wù)器端的代碼,允許API來(lái)始終保持同步2021-10-10
java基礎(chǔ)之標(biāo)簽、按鈕和按鈕事件簡(jiǎn)介
本文給大家?guī)?lái)的是java圖形界面的基礎(chǔ)知識(shí),簡(jiǎn)單介紹了標(biāo)簽、按鈕和按鈕事件,十分的詳細(xì),有需要的小伙伴可以參考下。2015-06-06
GSON實(shí)現(xiàn)Java對(duì)象的JSON序列化與反序列化的實(shí)例教程
GSON是Google開(kāi)發(fā)并開(kāi)源的一個(gè)Java的JSON轉(zhuǎn)換庫(kù),這里我們將來(lái)講解GSON實(shí)現(xiàn)Java對(duì)象的JSON序列化與反序列化的實(shí)例教程,需要的朋友可以參考下2016-06-06
springBoot啟動(dòng)報(bào)錯(cuò)log4j沖突的解決方案
這篇文章主要介紹了springBoot啟動(dòng)報(bào)錯(cuò)log4j沖突的解決方案,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。2021-07-07
Java并發(fā)編程Callable與Future的應(yīng)用實(shí)例代碼
這篇文章主要介紹了Java并發(fā)編程Callable與Future的應(yīng)用實(shí)例代碼,具有一定借鑒價(jià)值,需要的朋友可以參考下2018-01-01

