springmvc中使用interceptor攔截

`HandlerInterceptor` 是Spring MVC中用于在請求處理之前、之后以及完成之后執行邏輯的接口。它與Servlet的`Filter`類似,但更加靈活,因為它可以訪問Spring的上下文和模型數據。`HandlerInterceptor` 常用于日志記錄、權限驗證、性能監控等場景。

### **1. 創建自定義 `HandlerInterceptor`**

要使用 `HandlerInterceptor`,你需要實現 `HandlerInterceptor` 接口,并重寫以下方法:

- `preHandle(HttpServletRequest request, HttpServletResponse response, Object handler)`:在請求處理之前被調用,返回`true`表示繼續執行后續的攔截器或Controller,返回`false`表示中斷執行。
- `postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView)`:在請求處理之后被調用,但視圖渲染之前。
- `afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex)`:在請求處理完成之后被調用,無論是否發生異常。

以下是一個簡單的自定義 `HandlerInterceptor` 示例:

```java
import org.springframework.web.servlet.HandlerInterceptor;
import org.springframework.web.servlet.ModelAndView;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

public class CustomInterceptor implements HandlerInterceptor {

? ? @Override
? ? public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
? ? ? ? // 請求處理之前執行
? ? ? ? System.out.println("Pre Handle method is Calling");
? ? ? ? System.out.println("Request URL: " + request.getRequestURL());
? ? ? ? return true; // 返回true繼續執行后續邏輯,返回false中斷執行
? ? }

? ? @Override
? ? public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception {
? ? ? ? // 請求處理之后執行
? ? ? ? System.out.println("Post Handle method is Calling");
? ? ? ? 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("Request and Response is completed");
? ? ? ? if (ex != null) {
? ? ? ? ? ? System.out.println("Exception occurred: " + ex.getMessage());
? ? ? ? }
? ? }
}
```

### **2. 注冊 `HandlerInterceptor`**

在Spring MVC中,可以通過 `WebMvcConfigurer` 接口注冊 `HandlerInterceptor`。以下是一個示例:

```java
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.WebMvcConfigurer;

@Configuration
public class WebConfig implements WebMvcConfigurer {

? ? @Autowired
? ? private CustomInterceptor customInterceptor;

? ? @Override
? ? public void addInterceptors(InterceptorRegistry registry) {
? ? ? ? // 注冊自定義攔截器,指定攔截路徑
? ? ? ? registry.addInterceptor(customInterceptor)
? ? ? ? ? ? ? ? .addPathPatterns("/api/**") // 攔截/api路徑下的所有請求
? ? ? ? ? ? ? ? .excludePathPatterns("/api/public/**"); // 排除/api/public路徑下的請求
? ? }
}
```

### **3. 測試 `HandlerInterceptor`**

啟動Spring Boot應用后,訪問 `/api/**` 路徑下的任何接口,`CustomInterceptor` 都會攔截請求并執行相應的邏輯。

### **4. 使用場景**
- **日志記錄**:記錄請求的URL、參數、響應時間等。
- **權限驗證**:在 `preHandle` 方法中檢查用戶是否登錄,是否有權限訪問某個資源。
- **性能監控**:在 `preHandle` 和 `afterCompletion` 方法中記錄請求處理的時間。
- **數據預處理**:在 `postHandle` 方法中修改模型數據或視圖。

### **5. 完整示例**

以下是一個完整的Spring Boot項目示例,包含自定義 `HandlerInterceptor` 和注冊邏輯:

#### **`CustomInterceptor.java`**
```java
import org.springframework.web.servlet.HandlerInterceptor;
import org.springframework.web.servlet.ModelAndView;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

public class CustomInterceptor implements HandlerInterceptor {

? ? @Override
? ? public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
? ? ? ? System.out.println("Pre Handle method is Calling");
? ? ? ? System.out.println("Request URL: " + request.getRequestURL());
? ? ? ? return true;
? ? }

? ? @Override
? ? public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception {
? ? ? ? System.out.println("Post Handle method is Calling");
? ? ? ? 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("Request and Response is completed");
? ? ? ? if (ex != null) {
? ? ? ? ? ? System.out.println("Exception occurred: " + ex.getMessage());
? ? ? ? }
? ? }
}
```

#### **`WebConfig.java`**
```java
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.WebMvcConfigurer;

@Configuration
public class WebConfig implements WebMvcConfigurer {

? ? @Autowired
? ? private CustomInterceptor customInterceptor;

? ? @Override
? ? public void addInterceptors(InterceptorRegistry registry) {
? ? ? ? registry.addInterceptor(customInterceptor)
? ? ? ? ? ? ? ? .addPathPatterns("/api/**")
? ? ? ? ? ? ? ? .excludePathPatterns("/api/public/**");
? ? }
}
```

#### **`Controller` 示例**
```java
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;

@RestController
public class TestController {

? ? @GetMapping("/api/test")
? ? public String test() {
? ? ? ? return "Hello, World!";
? ? }

? ? @GetMapping("/api/public/test")
? ? public String publicTest() {
? ? ? ? return "This is a public endpoint";
? ? }
}
```

### **6. 輸出示例**
訪問 `/api/test` 時,控制臺輸出:
```
Pre Handle method is Calling
Request URL: http://localhost:8080/api/test
Post Handle method is Calling
Request and Response is completed
```

訪問 `/api/public/test` 時,控制臺不會輸出攔截器的日志,因為該路徑被排除了。

通過以上方法,你可以輕松地在Spring項目中使用 `HandlerInterceptor` 來實現各種功能。

下面這個例子是使用了自定義注解方式

在Spring中結合`HandlerInterceptor`和自定義注解可以實現靈活的請求處理邏輯,例如權限校驗、日志記錄等。以下是一個完整的示例,展示如何定義自定義注解,并在`HandlerInterceptor`中使用它。

### **1. 定義自定義注解**

首先,定義一個自定義注解,用于標記需要特殊處理的Controller方法。例如,定義一個`@Loggable`注解,用于記錄方法的調用信息:

```java
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;

@Target(ElementType.METHOD) // 僅適用于方法
@Retention(RetentionPolicy.RUNTIME) // 運行時保留
public @interface Loggable {
? ? String value() default ""; // 可選的描述信息
}
```

### **2. 創建攔截器**

接下來,創建一個`HandlerInterceptor`實現類,用于在請求處理前后執行邏輯:

```java
import org.springframework.web.method.HandlerMethod;
import org.springframework.web.servlet.HandlerInterceptor;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

public class LoggingInterceptor implements HandlerInterceptor {

? ? @Override
? ? public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
? ? ? ? if (handler instanceof HandlerMethod) {
? ? ? ? ? ? HandlerMethod handlerMethod = (HandlerMethod) handler;
? ? ? ? ? ? Loggable loggable = handlerMethod.getMethodAnnotation(Loggable.class);
? ? ? ? ? ? if (loggable != null) {
? ? ? ? ? ? ? ? // 獲取注解的值
? ? ? ? ? ? ? ? String description = loggable.value();
? ? ? ? ? ? ? ? System.out.println("Logging: " + description);
? ? ? ? ? ? }
? ? ? ? }
? ? ? ? return true; // 繼續后續處理
? ? }

? ? @Override
? ? public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception {
? ? ? ? System.out.println("Request completed");
? ? }
}
```

### **3. 注冊攔截器**

在Spring配置中注冊攔截器,使其生效:

```java
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.WebMvcConfigurer;

@Configuration
public class WebConfig implements WebMvcConfigurer {

? ? @Autowired
? ? private LoggingInterceptor loggingInterceptor;

? ? @Override
? ? public void addInterceptors(InterceptorRegistry registry) {
? ? ? ? registry.addInterceptor(loggingInterceptor)
? ? ? ? ? ? ? ? .addPathPatterns("/**") // 攔截所有路徑
? ? ? ? ? ? ? ? .excludePathPatterns("/static/**", "/css/**", "/js/**"); // 排除靜態資源
? ? }
}
```

### **4. 使用自定義注解**

在Controller方法上使用自定義注解:

```java
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;

@RestController
public class ExampleController {

? ? @GetMapping("/example")
? ? @Loggable(value = "This is an example method")
? ? public String exampleMethod() {
? ? ? ? return "Hello, World!";
? ? }
}
```

### **5. 測試**

啟動Spring Boot應用后,訪問`/example`路徑,控制臺將輸出類似以下內容:

```
Logging: This is an example method
Request completed
```

### **總結**

通過定義自定義注解并結合`HandlerInterceptor`,可以在Spring MVC中靈活地為特定方法添加額外的處理邏輯,例如日志記錄、權限校驗等。這種方法使得代碼更加清晰且易于維護。

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/news/898533.shtml
繁體地址,請注明出處:http://hk.pswp.cn/news/898533.shtml
英文地址,請注明出處:http://en.pswp.cn/news/898533.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

【網絡協議】基于UDP的可靠協議:KCP

TCP是為流量設計的(每秒內可以傳輸多少KB的數據),講究的是充分利用帶寬。而 KCP是為流速設計的(單個數據包從一端發送到一端需要多少時間),以10%-20%帶寬浪費的代價換取了比 TCP快30%-40%的傳輸速度。TCP信…

【論文閱讀】Contrastive Clustering Learning for Multi-Behavior Recommendation

論文地址:Contrastive Clustering Learning for Multi-Behavior Recommendation | ACM Transactions on Information Systems 摘要 近年來,多行為推薦模型取得了顯著成功。然而,許多模型未充分考慮不同行為之間的共性與差異性,以…

藍橋杯2023年第十四屆省賽真題-子矩陣

題目來自DOTCPP: 暴力思路(兩個測試點超時): 題目要求我們求出子矩陣的最大值和最小值的乘積,我們可以枚舉矩陣中的所有點,以這個點為其子矩陣的左上頂點,然后判斷一下能不能構成子矩陣。如果可…

centos 磁盤重新分割,將原來/home 下部分空間轉移到 / 根目錄下

上次重裝系統時,不小心將一半磁盤放在了 /home 下面,運行一段時間后,發現/home 空間沒有怎么用,反而是/ 目錄報警說磁盤用完了,準備將 /home下的空間分一部分給主目錄 / 先查看下 空間分布情況 df -lh 可以看到&…

【C#語言】C#同步與異步編程深度解析:讓程序學會“一心多用“

文章目錄 ?前言?一、同步編程:單線程的線性世界🌟1、尋找合適的對象?1) 🌟7、設計應支持變化 ?二、異步編程:多任務的協奏曲?三、async/await工作原理揭秘?四、最佳實踐與性能陷阱?五、異步編程適用場景?六、性能對比實測…

Redis命令詳解--集合

Redis set 是string類型的無序集合。集合成員是唯一的,這就意味著集合中不能出現重復的數據,常用命令: SADD key member1 [member2...] 向集合添加一個或多個成員 SREM key member1 [member2...] 移除集合中一個或多個成員 SMEMBERS key 獲…

學習筆記 ASP.NET Core Web API 8.0部署到iis

一.修改配置文件 修改Program.cs配置文件將 if (app.Environment.IsDevelopment()) {app.UseSwagger();app.UseSwaggerUI(); }修改為 app.UseSwagger(); app.UseSwaggerUI(); 二.安裝ASP.NET Core Runtime 8.0.14 文件位置https://dotnet.microsoft.com/en-us/download/do…

配置 VSCode 的 C# 開發環境

1. 安裝必要的依賴 1.1 VSCode 擴展 安裝 C# 相關插件(如 C#、C# Extensions 等)。 1.2 .NET SDK 下載地址:.NET SDK 下載頁面 1.3 安裝檢測 在命令行輸入以下命令,如果正確返回了版本號,則表示 .NET SDK 安裝成…

從零搭建微服務項目Pro(第6-1章——Spring Security+JWT實現用戶鑒權訪問與token刷新)

前言: 在現代的微服務架構中,用戶鑒權和訪問控制是非常重要的一部分。Spring Security 是 Spring 生態中用于處理安全性的強大框架,而 JWT(JSON Web Token)則是一種輕量級的、自包含的令牌機制,廣泛用于分…

使用HAI來打通DeepSeek的任督二脈

一、什么是HAI HAI是一款專注于AI與科學計算領域的云服務產品,旨在為開發者、企業及科研人員提供高效、易用的算力支持與全棧解決方案。主要使用場景為: AI作畫,AI對話/寫作、AI開發/測試。 二、開通HAI 選擇CPU算力 16核32GB,這…

【保姆級】阿里云codeup配置Git的CI/CD步驟

以下是通過阿里云CodeUp的Git倉庫進行CI/CD配置的詳細步驟,涵蓋前端(Vue 3)和后端(Spring Boot)項目的自動化打包,并將前端打包結果嵌入到Nginx的Docker鏡像中,以及將后端打包的JAR文件拷貝至Do…

LINUX網絡編程API原型詳細解析

1. 網絡體系 1.1. 簡介 網絡采用分而治之的方法設計,將網絡的功能劃分為不同的模塊,以分層的形式有機組合在一起。 每層實現不同的功能,其內部實現方法對外部其他層次來說是透明的。每層向上層提供服務,同時使用下層提供…

藍橋杯 之 暴力回溯

文章目錄 數字接龍小u的最大連續移動次數問題迷宮 在藍橋杯中,十分喜歡考察對于網格的回溯的問題,對于這類的問題,常常會使用到這個DFS和BFS進行考察,不過無論怎么考察,都只是會在最基礎的模本的基礎上,根據…

微信小程序的業務域名配置(通過ingress網關的注解)

一、背景 微信小程序的業務域名配置(通過kong網關的pre-function配置)是依靠kong實現,本文將通過ingress網關實現。 而我們的服務是部署于阿里云K8S容器,當然內核與ingress無異。 找到k8s–>網絡–>路由 二、ingress注解 …

Python數據可視化工具:六西格瑪及其基礎工具概覽

在當今數據驅動的時代,數據分析和可視化工具成為了各行業優化流程、提升質量的關鍵手段。六西格瑪(Six Sigma)作為一種以數據為基礎、追求完美質量的管理理念,其實施依賴于一系列基礎工具的靈活運用。而Python,憑借其強…

集群環境下Redis 商品庫存系統設計

目錄 環境實現基本結構代碼業務代碼主體庫存管理模塊 后續問題高并發臨界值與樂觀鎖問題 完整代碼總結后話 環境 我們現在要做商品秒殺系統。功能很簡單,就是庫存刪減。用戶先下單減庫存,之后再進行扣款。 實現 基本結構代碼 那么我們先看下如何搭建…

Spring MVC響應數據

handler方法分析 /*** TODO: 一個controller的方法是控制層的一個處理器,我們稱為handler* TODO: handler需要使用RequestMapping/GetMapping系列,聲明路徑,在HandlerMapping中注冊,供DS查找!* TODO: handler作用總結:* 1.接收請求參數(param,json,pathVariable,共享域等…

基于圖像識別的醫學影像大數據診斷系統的設計與實現

標題:基于圖像識別的醫學影像大數據診斷系統的設計與實現 內容:1.摘要 隨著醫學影像技術的快速發展,醫學影像數據量呈爆炸式增長,傳統的人工診斷方式在處理海量數據時效率低下且容易出現誤差。本研究的目的是設計并實現一個基于圖像識別的醫學影像大數據…

Python散點圖(Scatter Plot):數據探索的“第一張圖表”

在數據可視化領域,散點圖是一種強大而靈活的工具,它能夠幫助我們直觀地理解和探索數據集中變量之間的關系。本文將深入探討散點圖的核心原理、應用場景以及如何使用Python進行高效繪制。 后續幾篇將介紹高級技巧、復雜應用場景。 Python散點圖(Scatter Plot):高階分析、散點…

【redis】在 Spring中操作 Redis

文章目錄 基礎設置依賴StringRedisTemplate庫的封裝 運行StringList刪庫 SetHashZset 基礎設置 依賴 需要選擇這個依賴 StringRedisTemplate // 后續 redis 測試的各種方法,都通過這個 Controller 提供的 http 接口來觸發 RestController public class MyC…