Java中攔截器的使用實現步驟
一、攔截器的作用與執(zhí)行時機
- 三個核心方法:
- preHandle(): 在Controller方法執(zhí)行前調用(用于權限驗證等)
- postHandle(): 在Controller方法執(zhí)行后、視圖渲染前調用(可修改ModelAndView)
- afterCompletion(): 在請求完全結束后調用(資源清理、日志記錄)
- 執(zhí)行流程:

二、實現步驟
步驟1:創(chuàng)建自定義攔截器
實現繼承 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í)行前調用
@Override
public boolean preHandle(HttpServletRequest request,
HttpServletResponse response,
Object handler) throws Exception {
System.out.println("--- preHandle executed ---");
// 示例:驗證登錄
if (request.getSession().getAttribute("user") == null) {
response.sendRedirect("/login"); // 重定向到登錄頁
return false; // 中斷請求
}
return true; // 放行請求
}
// Controller執(zhí)行后、視圖渲染前調用
@Override
public void postHandle(HttpServletRequest request,
HttpServletResponse response,
Object handler,
ModelAndView modelAndView) throws Exception {
System.out.println("--- postHandle executed ---");
// 可修改ModelAndView數據
if (modelAndView != null) {
modelAndView.addObject("timestamp", System.currentTimeMillis());
}
}
// 請求完全結束后調用(視圖渲染完畢)
@Override
public void afterCompletion(HttpServletRequest request,
HttpServletResponse response,
Object handler,
Exception ex) throws Exception {
System.out.println("--- afterCompletion executed ---");
// 資源清理或記錄請求耗時
}
}步驟2:注冊攔截器到Spring MVC
創(chuàng)建配置類實現 繼承 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:測試Controller
@RestController
public class TestController {
@GetMapping("/home")
public String home() {
return "Welcome to home page!";
}
@GetMapping("/login")
public String login() {
return "Login page";
}
}三、關鍵配置詳解
- 路徑匹配規(guī)則:
- addPathPatterns("/admin/**"):攔截以 /admin/ 開頭的所有路徑
- excludePathPatterns("/public/**"):排除靜態(tài)資源
- 多攔截器順序:
registry.addInterceptor(new LogInterceptor()).order(1); // 數字越小優(yōu)先級越高 registry.addInterceptor(new AuthInterceptor()).order(2);
執(zhí)行順序:
LogInterceptor.preHandle → AuthInterceptor.preHandle → Controller →
AuthInterceptor.postHandle → LogInterceptor.postHandle →
視圖渲染 → AuthInterceptor.afterCompletion → LogInterceptor.afterCompletion
四、常見使用場景
- 身份認證:在 preHandle() 中校驗Session/Token
- 日志記錄:在 afterCompletion() 記錄請求耗時
- 參數預處理:在 preHandle() 中統(tǒng)一處理請求參數
- 全局數據注入:在 postHandle() 中向Model添加公共數據
五、攔截器 vs 過濾器(Filter)
特性 | 攔截器 (Interceptor) | 過濾器 (Filter) |
歸屬 | Spring MVC 機制 | Servlet 規(guī)范 |
作用范圍 | 僅針對Controller請求 | 所有請求(包括靜態(tài)資源) |
依賴 | 可訪問Spring容器中的Bean | 無法直接使用Spring Bean |
執(zhí)行時機 | Controller方法前后 | Servlet處理前后 |
實例化 | 受Spring管理(支持依賴注入) | 由Web服務器管理 |
提示:優(yōu)先使用攔截器處理Controller相關邏輯,過濾器更適合處理底層Servlet請求(如編碼轉換)。
六、最佳實踐
- 避免阻塞操作:攔截器中不要執(zhí)行耗時任務(影響吞吐量)
- 謹慎使用postHandle:如果Controller有 @ResponseBody,postHandle 不會生效(無視圖渲染)
- 注入Bean的正確方式:
@Component
public class AuthInterceptor implements HandlerInterceptor {
@Autowired // 攔截器本身需由Spring管理
private UserService userService;
}
// 注冊時從容器獲取
registry.addInterceptor(authInterceptor); 通過以上步驟,您可以在Spring Boot中高效實現攔截邏輯。根據實際需求組合多個攔截器,構建靈活的處理鏈。
七、HandlerInterceptor 和 WebMvcConfigurer
在 Spring Boot 項目中,當創(chuàng)建攔截器時,我們需要處理兩個獨立的接口:HandlerInterceptor 和 WebMvcConfigurer
1. HandlerInterceptor 接口需要重寫的方法
當創(chuàng)建自定義攔截器時,需要實現 HandlerInterceptor 接口并重寫它的三個核心方法:
方法 | 說明 | 是否必須重寫 |
preHandle() | 在 Controller 方法執(zhí)行前調用 | ? 通常必須 |
postHandle() | 在 Controller 方法執(zhí)行后、視圖渲染前調用 | ?? 可選 |
afterCompletion() | 在請求完全結束后調用 | ?? 可選 |
public class AuthInterceptor implements HandlerInterceptor {
// 必須重寫(最常用)
@Override
public boolean preHandle(HttpServletRequest request,
HttpServletResponse response,
Object handler) {
// 認證邏輯
return true; // 返回 true 放行請求
}
// 可選重寫
@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接口需要重寫的方法
當注冊攔截器時,需要實現 WebMvcConfigurer 接口,但只需重寫一個方法:
方法 | 說明 | 是否必須重寫 |
addInterceptors() | 注冊自定義攔截器并配置攔截規(guī)則 | ? 必須 |
其他方法(與攔截器無關,可選重寫):
- addCorsMappings():配置跨域
- addResourceHandlers():靜態(tài)資源處理
- addViewControllers():視圖控制器
- 等 20+ 個默認方法(Java 8+ 的接口默認方法)
示例實現:
@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. 關鍵注意事項
- HandlerInterceptor 方法重寫規(guī)則
- preHandle() 必須返回 boolean(true=放行,false=中斷)
- postHandle() 僅在返回視圖時生效(對 @ResponseBody 無效)
- afterCompletion() 總是執(zhí)行(即使 Controller 拋出異常)
- WebMvcConfigurer 最佳實踐
@Configuration
public class WebConfig implements WebMvcConfigurer {
@Autowired // 推薦注入攔截器(不要new實例)
private AuthInterceptor authInterceptor;
@Override
public void addInterceptors(InterceptorRegistry registry) {
// 設置多攔截器順序
registry.addInterceptor(new LogInterceptor()).order(0);
registry.addInterceptor(authInterceptor).order(1)
.addPathPatterns("/secure/**");
}
}常見錯誤 :
- 錯誤1:忘記在配置類加 @Configuration
- 錯誤2:在 WebMvcConfigurer 中重寫了不需要的方法
- 錯誤3:在攔截器中 new 實例(應使用依賴注入)
5. 兩種接口的關系總結
特性 | HandlerInterceptor | WebMvcConfigurer |
角色 | 定義攔截邏輯 | 注冊攔截器 |
重寫方法 | preHandle() | addInterceptors() |
使用場景 | 業(yè)務邏輯實現 | 配置管理 |
實例數量 | 每個攔截器一個實現類 | 整個項目只需一個配置類 |
注解要求 | @Component(可選) | @Configuration(必須) |
?? 簡單記憶:
- HandlerInterceptor:定義 "做什么"(攔截邏輯)
- WebMvcConfigurer:定義 "對誰做"(攔截路徑)
總結
到此這篇關于Java中攔截器的使用實現的文章就介紹到這了,更多相關Java攔截器使用內容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關文章希望大家以后多多支持腳本之家!
相關文章
RocketMQ?broker?消息投遞流程處理PULL_MESSAGE請求解析
這篇文章主要為大家介紹了RocketMQ?broker?消息投遞流程處理PULL_MESSAGE請求源碼解析,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進步,早日升職加薪2023-04-04
Spring?Cloud?OAuth2實現自定義token返回格式
Spring?Security?OAuth的token返回格式都是默認的,但是往往這個格式是不適配系統(tǒng)。本文將用一個接口優(yōu)雅的實現?Spring?Cloud?OAuth2?自定義token返回格式,需要的可以參考一下2022-06-06
mybatis-plus常用注解@TableId和@TableField的用法
本文主要介紹了mybatis-plus常用注解@TableId和@TableField的用法,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友們下面隨著小編來一起學習學習吧2023-04-04
java中instanceof和getClass()的區(qū)別分析
本篇文章介紹了,在java中instanceof和getClass()的區(qū)別分析。需要的朋友參考下2013-04-04

