Java中攔截器的使用實(shí)現(xiàn)步驟
一、攔截器的作用與執(zhí)行時(shí)機(jī)
- 三個(gè)核心方法:
- preHandle(): 在Controller方法執(zhí)行前調(diào)用(用于權(quán)限驗(yàn)證等)
- postHandle(): 在Controller方法執(zhí)行后、視圖渲染前調(diào)用(可修改ModelAndView)
- afterCompletion(): 在請(qǐng)求完全結(jié)束后調(diào)用(資源清理、日志記錄)
- 執(zhí)行流程:

二、實(shí)現(xiàn)步驟
步驟1:創(chuàng)建自定義攔截器
實(shí)現(xiàn)繼承 HandlerInterceptor 接口:
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.springframework.web.servlet.HandlerInterceptor;
import org.springframework.web.servlet.ModelAndView;
public class AuthInterceptor implements HandlerInterceptor {
// Controller執(zhí)行前調(diào)用
@Override
public boolean preHandle(HttpServletRequest request,
HttpServletResponse response,
Object handler) throws Exception {
System.out.println("--- preHandle executed ---");
// 示例:驗(yàn)證登錄
if (request.getSession().getAttribute("user") == null) {
response.sendRedirect("/login"); // 重定向到登錄頁
return false; // 中斷請(qǐng)求
}
return true; // 放行請(qǐng)求
}
// Controller執(zhí)行后、視圖渲染前調(diào)用
@Override
public void postHandle(HttpServletRequest request,
HttpServletResponse response,
Object handler,
ModelAndView modelAndView) throws Exception {
System.out.println("--- postHandle executed ---");
// 可修改ModelAndView數(shù)據(jù)
if (modelAndView != null) {
modelAndView.addObject("timestamp", System.currentTimeMillis());
}
}
// 請(qǐng)求完全結(jié)束后調(diào)用(視圖渲染完畢)
@Override
public void afterCompletion(HttpServletRequest request,
HttpServletResponse response,
Object handler,
Exception ex) throws Exception {
System.out.println("--- afterCompletion executed ---");
// 資源清理或記錄請(qǐng)求耗時(shí)
}
}步驟2:注冊(cè)攔截器到Spring MVC
創(chuàng)建配置類實(shí)現(xiàn) 繼承 WebMvcConfigurer 接口:
import org.springframework.context.annotation.Configuration;
import org.springframework.web.servlet.config.annotation.InterceptorRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;
@Configuration
public class WebConfig implements WebMvcConfigurer {
@Override
public void addInterceptors(InterceptorRegistry registry) {
registry.addInterceptor(new AuthInterceptor())
.addPathPatterns("/**") // 攔截所有路徑
.excludePathPatterns("/login", "/css/**"); // 排除路徑
}
}步驟3:測(cè)試Controller
@RestController
public class TestController {
@GetMapping("/home")
public String home() {
return "Welcome to home page!";
}
@GetMapping("/login")
public String login() {
return "Login page";
}
}三、關(guān)鍵配置詳解
- 路徑匹配規(guī)則:
- addPathPatterns("/admin/**"):攔截以 /admin/ 開頭的所有路徑
- excludePathPatterns("/public/**"):排除靜態(tài)資源
- 多攔截器順序:
registry.addInterceptor(new LogInterceptor()).order(1); // 數(shù)字越小優(yōu)先級(jí)越高 registry.addInterceptor(new AuthInterceptor()).order(2);
執(zhí)行順序:
LogInterceptor.preHandle → AuthInterceptor.preHandle → Controller →
AuthInterceptor.postHandle → LogInterceptor.postHandle →
視圖渲染 → AuthInterceptor.afterCompletion → LogInterceptor.afterCompletion
四、常見使用場(chǎng)景
- 身份認(rèn)證:在 preHandle() 中校驗(yàn)Session/Token
- 日志記錄:在 afterCompletion() 記錄請(qǐng)求耗時(shí)
- 參數(shù)預(yù)處理:在 preHandle() 中統(tǒng)一處理請(qǐng)求參數(shù)
- 全局?jǐn)?shù)據(jù)注入:在 postHandle() 中向Model添加公共數(shù)據(jù)
五、攔截器 vs 過濾器(Filter)
特性 | 攔截器 (Interceptor) | 過濾器 (Filter) |
歸屬 | Spring MVC 機(jī)制 | Servlet 規(guī)范 |
作用范圍 | 僅針對(duì)Controller請(qǐng)求 | 所有請(qǐng)求(包括靜態(tài)資源) |
依賴 | 可訪問Spring容器中的Bean | 無法直接使用Spring Bean |
執(zhí)行時(shí)機(jī) | Controller方法前后 | Servlet處理前后 |
實(shí)例化 | 受Spring管理(支持依賴注入) | 由Web服務(wù)器管理 |
提示:優(yōu)先使用攔截器處理Controller相關(guān)邏輯,過濾器更適合處理底層Servlet請(qǐng)求(如編碼轉(zhuǎn)換)。
六、最佳實(shí)踐
- 避免阻塞操作:攔截器中不要執(zhí)行耗時(shí)任務(wù)(影響吞吐量)
- 謹(jǐn)慎使用postHandle:如果Controller有 @ResponseBody,postHandle 不會(huì)生效(無視圖渲染)
- 注入Bean的正確方式:
@Component
public class AuthInterceptor implements HandlerInterceptor {
@Autowired // 攔截器本身需由Spring管理
private UserService userService;
}
// 注冊(cè)時(shí)從容器獲取
registry.addInterceptor(authInterceptor); 通過以上步驟,您可以在Spring Boot中高效實(shí)現(xiàn)攔截邏輯。根據(jù)實(shí)際需求組合多個(gè)攔截器,構(gòu)建靈活的處理鏈。
七、HandlerInterceptor 和 WebMvcConfigurer
在 Spring Boot 項(xiàng)目中,當(dāng)創(chuàng)建攔截器時(shí),我們需要處理兩個(gè)獨(dú)立的接口:HandlerInterceptor 和 WebMvcConfigurer
1. HandlerInterceptor 接口需要重寫的方法
當(dāng)創(chuàng)建自定義攔截器時(shí),需要實(shí)現(xiàn) HandlerInterceptor 接口并重寫它的三個(gè)核心方法:
方法 | 說明 | 是否必須重寫 |
preHandle() | 在 Controller 方法執(zhí)行前調(diào)用 | ? 通常必須 |
postHandle() | 在 Controller 方法執(zhí)行后、視圖渲染前調(diào)用 | ?? 可選 |
afterCompletion() | 在請(qǐng)求完全結(jié)束后調(diào)用 | ?? 可選 |
public class AuthInterceptor implements HandlerInterceptor {
// 必須重寫(最常用)
@Override
public boolean preHandle(HttpServletRequest request,
HttpServletResponse response,
Object handler) {
// 認(rèn)證邏輯
return true; // 返回 true 放行請(qǐng)求
}
// 可選重寫
@Override
public void postHandle(HttpServletRequest request,
HttpServletResponse response,
Object handler,
ModelAndView modelAndView) {
// 后處理邏輯
}
// 可選重寫
@Override
public void afterCompletion(HttpServletRequest request,
HttpServletResponse response,
Object handler,
Exception ex) {
// 清理資源
}
}2. WebMvcConfigurer接口需要重寫的方法
當(dāng)注冊(cè)攔截器時(shí),需要實(shí)現(xiàn) WebMvcConfigurer 接口,但只需重寫一個(gè)方法:
方法 | 說明 | 是否必須重寫 |
addInterceptors() | 注冊(cè)自定義攔截器并配置攔截規(guī)則 | ? 必須 |
其他方法(與攔截器無關(guān),可選重寫):
- addCorsMappings():配置跨域
- addResourceHandlers():靜態(tài)資源處理
- addViewControllers():視圖控制器
- 等 20+ 個(gè)默認(rèn)方法(Java 8+ 的接口默認(rèn)方法)
示例實(shí)現(xiàn):
@Configuration
public class WebConfig implements WebMvcConfigurer {
// 必須重寫(唯一需要重寫的方法)
@Override
public void addInterceptors(InterceptorRegistry registry) {
registry.addInterceptor(new AuthInterceptor())
.addPathPatterns("/**") // 攔截所有路徑
.excludePathPatterns("/login"); // 排除登錄頁
}
// 其他方法不需要重寫(除非有特殊需求)
// 例如跨域配置(可選)
@Override
public void addCorsMappings(CorsRegistry registry) {
registry.addMapping("/**").allowedOrigins("*");
}
}3. 完整流程圖示

4. 關(guān)鍵注意事項(xiàng)
- HandlerInterceptor 方法重寫規(guī)則
- preHandle() 必須返回 boolean(true=放行,false=中斷)
- postHandle() 僅在返回視圖時(shí)生效(對(duì) @ResponseBody 無效)
- afterCompletion() 總是執(zhí)行(即使 Controller 拋出異常)
- WebMvcConfigurer 最佳實(shí)踐
@Configuration
public class WebConfig implements WebMvcConfigurer {
@Autowired // 推薦注入攔截器(不要new實(shí)例)
private AuthInterceptor authInterceptor;
@Override
public void addInterceptors(InterceptorRegistry registry) {
// 設(shè)置多攔截器順序
registry.addInterceptor(new LogInterceptor()).order(0);
registry.addInterceptor(authInterceptor).order(1)
.addPathPatterns("/secure/**");
}
}常見錯(cuò)誤 :
- 錯(cuò)誤1:忘記在配置類加 @Configuration
- 錯(cuò)誤2:在 WebMvcConfigurer 中重寫了不需要的方法
- 錯(cuò)誤3:在攔截器中 new 實(shí)例(應(yīng)使用依賴注入)
5. 兩種接口的關(guān)系總結(jié)
特性 | HandlerInterceptor | WebMvcConfigurer |
角色 | 定義攔截邏輯 | 注冊(cè)攔截器 |
重寫方法 | preHandle() | addInterceptors() |
使用場(chǎng)景 | 業(yè)務(wù)邏輯實(shí)現(xiàn) | 配置管理 |
實(shí)例數(shù)量 | 每個(gè)攔截器一個(gè)實(shí)現(xiàn)類 | 整個(gè)項(xiàng)目只需一個(gè)配置類 |
注解要求 | @Component(可選) | @Configuration(必須) |
?? 簡單記憶:
- HandlerInterceptor:定義 "做什么"(攔截邏輯)
- WebMvcConfigurer:定義 "對(duì)誰做"(攔截路徑)
總結(jié)
到此這篇關(guān)于Java中攔截器的使用實(shí)現(xiàn)的文章就介紹到這了,更多相關(guān)Java攔截器使用內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
springmvc處理響應(yīng)數(shù)據(jù)的解析
今天小編就為大家分享一篇關(guān)于springmvc處理響應(yīng)數(shù)據(jù)的解析,小編覺得內(nèi)容挺不錯(cuò)的,現(xiàn)在分享給大家,具有很好的參考價(jià)值,需要的朋友一起跟隨小編來看看吧2019-01-01
Java8?Optional常用方法使用場(chǎng)景分析
這篇文章主要介紹了Java8?Optional常用方法使用場(chǎng)景,具有很好的參考價(jià)值,希望對(duì)大家有所幫助,如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2024-06-06
Spring?Boot?集成JWT實(shí)現(xiàn)前后端認(rèn)證的示例代碼
小程序、H5應(yīng)用的快速發(fā)展,使得前后端分離已經(jīng)成為了趨勢(shì),本文主要介紹了Spring?Boot?集成JWT實(shí)現(xiàn)前后端認(rèn)證,文中通過示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2022-04-04
Java異常鏈表throw結(jié)構(gòu)assert詳細(xì)解讀
這篇文章主要給大家介紹了關(guān)于Java中方法使用的相關(guān)資料,文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧2021-08-08
RocketMQ?broker?消息投遞流程處理PULL_MESSAGE請(qǐng)求解析
這篇文章主要為大家介紹了RocketMQ?broker?消息投遞流程處理PULL_MESSAGE請(qǐng)求源碼解析,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪2023-04-04
Spring?Cloud?OAuth2實(shí)現(xiàn)自定義token返回格式
Spring?Security?OAuth的token返回格式都是默認(rèn)的,但是往往這個(gè)格式是不適配系統(tǒng)。本文將用一個(gè)接口優(yōu)雅的實(shí)現(xiàn)?Spring?Cloud?OAuth2?自定義token返回格式,需要的可以參考一下2022-06-06
mybatis-plus常用注解@TableId和@TableField的用法
本文主要介紹了mybatis-plus常用注解@TableId和@TableField的用法,文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧2023-04-04
java中instanceof和getClass()的區(qū)別分析
本篇文章介紹了,在java中instanceof和getClass()的區(qū)別分析。需要的朋友參考下2013-04-04

