SpringBoot學習(過濾器Filter。攔截器Interceptor。全局異常捕獲處理器GlobalExceptionHandler)(詳細使用教程)

目錄

一、過濾器Filter。

1.1定義與規范。

1.2工作原理與范圍。

1.3使用場景。

1.4 SpringBoot實現過濾器。(Filter配置2種方式)

<1>注解配置(@WebFilter、@Order、@ServletComponentScan)。

創建過濾器類。

啟用 Servlet 組件掃描。

<2>配置類注冊過濾器(FilterRegistrationBean對象配置)。

創建過濾器類。(無須使用第1種方式的注解)

配置過濾器。

二、攔截器Interceptor。

2.1定義與框架。

2.2工作原理與范圍。

2.3使用場景。

2.4 SpringBoot實現攔截器。

<1>創建攔截器類(實現 HandlerInterceptor 接口)。

日志記錄。(SLF4J、Logback)

多線程處理。(ThreadLocal)

<2>創建攔截器配置類(實現 WebMvcConfigurer 接口)。

三、全局異常捕獲處理器GlobalExceptionHandler。

3.1?全局異常捕獲處理器定義與實現方法。

3.2 SpringBoot實現全局異常捕獲處理器。

<1>自定義響應結果封裝類。(Result類)

<2>自定義全局異常捕獲處理類。(GlobalExceptionHandler類)

<3>模擬產生異常的XxxController類。


一、過濾器Filter。

1.1定義與規范。
  • Filter 是 Servlet 技術中的重要組件 ,遵循 Java Servlet 規范。
  • 由 Servlet 容器(如 Tomcat)管理其生命周期。包括init(初始化)doFilter(執行過濾操作)destroy(銷毀)方法
  • 過濾器生命周期由 Servlet 容器管理。
1.2工作原理與范圍。
  • 過濾器的核心:攔截客戶端請求和服務器響應。(請求的預處理、響應的后處理
  • 可以對 Web 服務器管理的所有 Web 資源(如 JSP、Servlet、靜態圖片、靜態 HTML 文件等)進行攔截
  • 在請求到達 Servlet 之前或響應離開 Servlet 之后,對請求和響應進行預處理和后處理。
1.3使用場景。
  • 常用于實現 URL 級別的權限訪問控制、過濾敏感詞匯、壓縮響應信息、設置字符編碼、記錄請求日志等通用功能 。
  • 如:在電商網站中,可過濾用戶輸入中的敏感詞,防止非法內容提交。或在應用入口處,對所有請求進行日志記錄,便于追蹤和排查問題。
1.4 SpringBoot實現過濾器。(Filter配置2種方式)
<1>注解配置(@WebFilter、@Order、@ServletComponentScan)。
  • 創建過濾器類。
  • 創建一個過濾器類(XxxFilter)實現 jakarta.servlet.Filter接口?,并重寫init()、doFilter()、destroy()方法。
  • 指定過濾器順序(補充)。若存在多個過濾器且執行順序重要,可使用@Order注解指定順序數字越小優先級越高。如@Order(1) 。
package com.hyl.filter;import jakarta.servlet.*;
import jakarta.servlet.annotation.WebFilter;import java.io.IOException;@WebFilter(urlPatterns = "/*", filterName = "logFilter")
public class LogFilter implements Filter {@Overridepublic void init(FilterConfig filterConfig) throws ServletException {System.out.println("LogFilter init,,,");}@Overridepublic void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {System.out.println("LogFilter doFilter,,,");long timeNow = System.currentTimeMillis();filterChain.doFilter(servletRequest,servletResponse);System.out.println("LogFilter doFilter,,,"+"耗時:"+(System.currentTimeMillis()-timeNow));}@Overridepublic void destroy() {System.out.println("LogFilter destroy,,,");}
}

  • 啟用 Servlet 組件掃描。
  • 在 Spring Boot 主類上添加 @ServletComponentScan 注解,掃描過濾器類(XxxFilter)。
package com.hyl;import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.boot.web.servlet.ServletComponentScan;@SpringBootApplication
@ServletComponentScan("com.hyl.filter")
public class SpringbootApplication {public static void main(String[] args) {SpringApplication.run(SpringbootApplication.class, args);}}

  • 發起請求。查看過濾器執行結果。



<2>配置類注冊過濾器(FilterRegistrationBean對象配置)。
  • 創建過濾器類。(無須使用第1種方式的注解)
package com.hyl.filter;import jakarta.servlet.*;
import java.io.IOException;public class LogFilter implements Filter {@Overridepublic void init(FilterConfig filterConfig) throws ServletException {System.out.println("LogFilter init,,,");}@Overridepublic void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {System.out.println("LogFilter doFilter,,,");long timeNow = System.currentTimeMillis();filterChain.doFilter(servletRequest,servletResponse);System.out.println("LogFilter doFilter,,,"+"耗時:"+(System.currentTimeMillis()-timeNow));}@Overridepublic void destroy() {System.out.println("LogFilter destroy,,,");}
}

  • 配置過濾器。
  • 創建配置類,通過 FilterRegistrationBean 注冊過濾器。其中可設置過濾的 URL 路徑、過濾器名稱、執行順序等。
package com.hyl.config;import com.hyl.filter.LogFilter;
import org.springframework.boot.web.servlet.FilterRegistrationBean;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;/*** 過濾器配置類:用于注冊和配置自定義過濾器*/
@Configuration
public class FilterConfig {@Bean  // 聲明將此方法的返回值作為Spring容器中的Bean管理public FilterRegistrationBean<LogFilter> logFilterRegistration(){FilterRegistrationBean<LogFilter> registration  = new FilterRegistrationBean<>();  // 創建過濾器注冊Bean實例(用于配置過濾器的屬性registration.setFilter(new LogFilter());  // 設置要注冊的過濾器實例registration.setBeanName("logFilter");  // 設置過濾器在Spring容器中的Bean名稱registration.setOrder(1);  // 設置過濾器的執行順序return registration;}
}

  • 發起請求。查看過濾器執行結果。


二、攔截器Interceptor。

2.1定義與框架。
  • 是 Spring MVC 框架中的核心組件 ,基于 Java 動態代理和 AOP(面向切面編程)實現,由 Spring 容器管理。
  • 攔截器生命周期由 Spring 容器管理。
2.2工作原理與范圍。
  • 工作在 Spring 的 DispatcherServlet 和具體的 Controller 之間
  • 當請求到達時,DispatcherServlet 根據配置的攔截器鏈對請求進行預處理,再轉發到相應 Controller響應返回時,也會經過攔截器鏈
  • 可在請求到達 Controller 之前、Controller 方法執行之后以及請求完成后進行攔截處理。
2.3使用場景。
  • 主要用于實現跨切面邏輯,如日志記錄性能統計安全控制(如權限驗證,判斷用戶是否有權限訪問特定資源)、事務處理、返回值處理等。
  • 如在某后臺管理系統中,使用攔截器檢查用戶是否登錄且具備操作權限(JWT令牌)。或在每次業務方法調用前后記錄時間,統計方法執行性能。
  • 過濾器適用于所有 Java Web 項目;攔截器僅適用于基于 Spring MVC 的項目
2.4 SpringBoot實現攔截器。
<1>創建攔截器類(實現 HandlerInterceptor 接口)。
  • 日志記錄。(SLF4J、Logback)
  • 使用 SLF4J(Simple Logging Facade for Java)作為日志門面,結合 Logback 作為具體的日志實現。通過 LoggerFactory.getLogger(LogInterceptor.class) 獲取日志記錄器

  • 多線程處理。(ThreadLocal)
  • 使用 ThreadLocal 來存儲與當前線程相關的請求時間記錄 ?。它為每個線程提供單獨的變量副本,避免多線程環境下數據錯亂,保證每個線程操作的是自己的請求時間記錄。最后在 afterCompletion() 方法中調用 remove() 方法及時清除數據,防止內存泄漏

package com.hyl.interceptor;import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.web.servlet.HandlerInterceptor;
import org.springframework.web.servlet.ModelAndView;import java.util.HashMap;
import java.util.Map;/*** 自定義攔截器:記錄請求耗時和路徑*/
public class LogInterceptor implements HandlerInterceptor {private static final Logger logger = LoggerFactory.getLogger(LogInterceptor.class);// 日志記錄Logbackprivate final ThreadLocal<Map<String, Object>> requestTime = new ThreadLocal<>(); // 線程安全的請求時間記錄/*** 請求處理前執行(Controller 方法調用前)*/@Overridepublic boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) {// 記錄請求開始時間long startTime = System.currentTimeMillis();Map<String, Object> timeMap = new HashMap<>();timeMap.put("startTime", startTime);timeMap.put("requestURI", request.getRequestURI()); // 記錄請求路徑requestTime.set(timeMap); // 存入 ThreadLocal 避免多線程沖突return true; // 返回 true 表示繼續處理請求,返回 false 則攔截請求}/*** 請求處理后執行(Controller方法調用后,視圖渲染前)*/@Overridepublic void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler,ModelAndView modelAndView) {}/*** 請求完成后執行(視圖渲染完成后)*/@Overridepublic void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) {// 從 ThreadLocal 中獲取請求時間記錄Map<String, Object> timeMap = requestTime.get();if (timeMap != null) {long endTime = System.currentTimeMillis();long duration = endTime - (Long) timeMap.get("startTime");  //總耗時String requestURI = timeMap.get("requestURI").toString();// 輸出日志:請求路徑、耗時logger.info("【攔截器日志】請求路徑:{},耗時:{}ms", requestURI, duration);requestTime.remove(); // 清除ThreadLocal數據,避免內存泄漏}}
}

<2>創建攔截器配置類(實現 WebMvcConfigurer 接口)。
package com.hyl.config;import com.hyl.interceptor.LogInterceptor;
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 InterceptorConfig implements WebMvcConfigurer {/*** 注冊攔截器到 Spring MVC 中,并配置攔截路徑*/@Overridepublic void addInterceptors(InterceptorRegistry registry) {LogInterceptor logInterceptor = new LogInterceptor(); // 創建攔截器實例registry.addInterceptor(logInterceptor) // 添加攔截器.addPathPatterns("/**") // 攔截所有路徑.excludePathPatterns("/static/**", "/favicon.ico"); // 排除靜態資源和圖標請求。防止干擾// 若有多個攔截器,可繼續調用addInterceptor()注冊// 可通過 .order(n) 設置攔截執行順序(n越小越先執行)}
}

  • 發起請求。查看攔截器執行結果。


  • 日志輸出級別:INFO。

三、全局異常捕獲處理器GlobalExceptionHandler。

3.1?全局異常捕獲處理器定義與實現方法。
  • 在 Spring 項目中,為統一處理異常,可創建全局異常處理類。
  • 1、通過在類上使用 @ControllerAdvice 注解,使其成為全局異常處理組件
  • 2、在類中的方法上使用 @ExceptionHandler 注解并指定攔截的異常類型如Exception.class 表示攔截所有異常)來處理對應異常。
  • 3、若返回字符串或 JSON 數據,需在方法上加 @ResponseBody 注解。
3.2 SpringBoot實現全局異常捕獲處理器。
<1>自定義響應結果封裝類。(Result類)
package com.hyl.pojo;import lombok.Data;//封裝響應結果類
@Data
public class Result {private String code;private String msg;private Object data;public Result() {}public Result(String code, String msg) {this.code = code;this.msg = msg;}public Result(String code, String msg, Object data) {this.code = code;this.msg = msg;this.data = data;}//響應success(無數據返回)public static Result success(){return new Result("200","操作成功");}//響應success(無數據返回)public static Result success(String msg){return new Result("200",msg);}//響應success(有數據返回)public static Result success(Object data) {return new Result("200","操作成功",data);}//響應success(有數據返回)public static Result success(String msg,Object data) {return new Result("200",msg,data);}//響應error(無數據返回)public static Result error(){return new Result("500","操作失敗");}//響應error(自定義異常信息提示)public static Result error(String code, String msg){Result result = new Result();result.setCode(code);result.setMsg(msg);return result;}}

<2>自定義全局異常捕獲處理類。(GlobalExceptionHandler類)
package com.hyl.exception;import com.hyl.pojo.Result;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.web.bind.annotation.ControllerAdvice;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.ResponseBody;// 標識該類為全局異常處理類,會對所有@Controller注解的控制器中拋出的異常進行統一捕獲處理
@ControllerAdvice
public class GlobalExceptionHandler {// 獲取日志記錄器,用于記錄異常相關信息private static final Logger log = LoggerFactory.getLogger(GlobalExceptionHandler.class);  // 日志記錄器@ExceptionHandler(Exception.class) // 聲明該方法用于處理所有類型為Exception及其子類的異常@ResponseBody  //返回值會直接作為HTTP響應體返回給客戶端public Result exceptionHandle(Exception e){System.out.println(e.getMessage());//存入日志log.info("全局異常處理器:"+e.getMessage());return Result.error("500","系統繁忙!");}
}

<3>模擬產生異常的XxxController類。
package com.hyl.controller;import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;@RestController
@RequestMapping("/test")
public class TestController {@GetMapping("/exception")public String exception() {// 模擬空指針異常String str = null;return str.length() + "";}
}

  • 發起請求。查看全局異常捕獲處理器執行結果。


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

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

相關文章

c++題目_P1443 馬的遍歷

P1443 馬的遍歷 # P1443 馬的遍歷 ## 題目描述 有一個 $n \times m$ 的棋盤&#xff0c;在某個點 $(x, y)$ 上有一個馬&#xff0c;要求你計算出馬到達棋盤上任意一個點最少要走幾步。 ## 輸入格式 輸入只有一行四個整數&#xff0c;分別為 $n, m, x, y$。 ## 輸出格式 …

清華《數據挖掘算法與應用》K-means聚類算法

使用k均值聚類算法對表4.1中的數據進行聚類。代碼參考P281。 創建一個名為 testSet.txt 的文本文件&#xff0c;將以下內容復制粘貼進去保存即可&#xff1a; 0 0 1 2 3 1 8 8 9 10 10 7 表4.1 # -*- coding: utf-8 -*- """ Created on Thu Apr 17 16:59:58 …

HarmonyOS-ArkUI V2工具類:AppStorageV2:應用全局UI狀態存儲

AppStorageV2是一個能夠跨界面存儲數據,管理數據的類。開發者可以使用AppStorageV2來存儲全局UI狀態變量數據。它提供的是應用級的全局共享能力,開發者可以通過connect綁定同一個key,進行跨ability數據共享。 概述 AppStorageV2是一個單例,創建時間是應用UI啟動時。其目的…

打靶日記 zico2: 1

一、探測靶機IP&#xff08;進行信息收集&#xff09; 主機發現 arp-scan -lnmap -sS -sV -T5 -p- 192.168.10.20 -A二、進行目錄枚舉 發現dbadmin目錄下有個test_db.php 進入后發現是一個登錄界面&#xff0c;嘗試弱口令&#xff0c;結果是admin&#xff0c;一試就出 得到加…

使用Java基于Geotools的SLD文件編程式創建與磁盤生成實戰

前言 在地理信息系統&#xff08;GIS&#xff09;領域&#xff0c;地圖的可視化呈現至關重要&#xff0c;而樣式定義語言&#xff08;SLD&#xff09;文件為地圖元素的樣式配置提供了強大的支持。SLD 能夠精確地定義地圖圖層中各類要素&#xff08;如點、線、面、文本等&#x…

kubernetes》》k8s》》Service

Kubernetes 中的 Service 是用于暴露應用服務的核心抽象&#xff0c;為 Pod 提供穩定的訪問入口、負載均衡和服務發現機制。Service在Kubernetes中代表了一組Pod的邏輯集合&#xff0c;通過創建一個Service&#xff0c;可以為一組具有相同功能的容器應用提供一個統一的入口地址…

【HDFS】EC重構過程中的校驗功能:DecodingValidator

一、動機 DecodingValidator是在HDFS-15759中引入的一個用于校驗EC數據重構正確性的組件。 先說下引入DecodingValidator的動機,據很多已知的ISSUE(如HDFS-14768, HDFS-15186, HDFS-15240,這些目前都已經fix了)反饋, EC在重構的時候可能會有各種各樣的問題,導致數據錯誤…

現代c++獲取linux系統架構

現代c獲取linux系統架構 前言一、使用命令獲取系統架構二、使用c代碼獲取系統架構三、驗證四、總結 前言 本文介紹一種使用c獲取linux系統架構的方法。 一、使用命令獲取系統架構 linux系統中可以使用arch或者uname -m命令來獲取當前系統架構&#xff0c;如下圖所示 archuna…

didFinishLaunching 與「主線程首次 idle」, 哪個是更優的啟動結束時間點 ?

結論先行 在這兩個候選時間點里—— application:didFinishLaunchingWithOptions: 執行結束主線程第一次進入 idle&#xff08;RunLoop kCFRunLoopBeforeWaiting&#xff09; 若你只能二選一&#xff0c;以「主線程首次 idle」作為 啟動結束 更合理。它比 didFinishLaunchin…

Vue3 + TypeScript中defineEmits 類型定義解析

TypeScript 中 Vue 3 的 defineEmits 函數的類型定義&#xff0c;用于聲明組件可以觸發的事件。以下是分步解釋&#xff1a; 1. 泛型定義 ts <"closeDialog" | "getApplySampleAndItemX"> 作用&#xff1a;定義允許的事件名稱集合&#xff0c;即組…

樹莓派超全系列教程文檔--(34)樹莓派配置GPIO

配置GPIO GPIO控制gpio 文章來源&#xff1a; http://raspberry.dns8844.cn/documentation 原文網址 GPIO控制 gpio 通過 gpio 指令&#xff0c;可以在啟動時將 GPIO 引腳設置為特定模式和值&#xff0c;而以前需要自定義 dt-blob.bin 文件。每一行都對一組引腳應用相同的設…

AladdinEdu(H卡GPU算力平臺)使用教程: 1)注冊與開通流程 2)插件使用流程

一、注冊與開通流程 首先進入AladdinEdu官網&#xff1a;AladdinEdu-同學們用得起的H卡算力平臺-高效做AI就上Aladdin 完成注冊&#xff0c;并進行學生認證&#xff1a;學生認證賬戶&#xff0c;認證期間享受教育優惠價。 登錄官網進入控制臺 二、插件使用流程 VScode中…

精益數據分析(6/126):深入理解精益分析的核心要點

精益數據分析&#xff08;6/126&#xff09;&#xff1a;深入理解精益分析的核心要點 在創業和數據驅動的時代浪潮中&#xff0c;我們都在不斷探索如何更好地利用數據推動業務發展。我希望通過和大家分享對《精益數據分析》的學習心得&#xff0c;一起在這個充滿挑戰和機遇的領…

2.深入剖析 Rust+Axum 類型安全路由系統

摘要 詳細解讀 RustAxum 路由系統的關鍵設計原理&#xff0c;涵蓋基于 Rust 類型系統的路由匹配機制、動態路徑參數與正則表達式驗證以及嵌套路由與模塊化組織等多種特性。 一、引言 在現代 Web 開發中&#xff0c;路由系統是構建 Web 應用的核心組件之一&#xff0c;它負責…

運籌學之模擬退火

目錄 一、歷史二、精髓思想三、案例與代碼實現 一、歷史 問&#xff1a;誰在什么時候提出模擬退火&#xff1f;答&#xff1a;模擬退火算法&#xff08;Simulated Annealing&#xff0c;SA&#xff09;是由斯圖爾特柯爾斯基&#xff08;Scott Kirkpatrick&#xff09; 等人在 …

android測試依賴

Android 項目中常用的測試相關庫 1. androidx.arch.core:core-testing:2.2.0 作用&#xff1a; 提供與 Android Architecture Components&#xff08;如 LiveData、ViewModel&#xff09;相關的測試工具。主要用于測試基于 LiveData 的異步操作。 常見功能&#xff1a; 即時…

stack,queue和priority_queue

1. stack 1.1 stack 的介紹 棧是一種容器適配器&#xff0c;專門設計用于LIFO環境&#xff08;后進先出&#xff09;&#xff0c;其中元素僅從容器的一端插入和提取。 容器適配器&#xff0c;也就是使用特定容器類的封裝對象作為其底層容器&#xff0c;提供一組特定的成員函…

MinnowBoard MAX單板UEFI BIOS代碼編譯教程

此教程用于UEFI EDK2代碼的研究&#xff0c;雖然EDK2框架代碼開源&#xff0c;但是都是在模擬器上跑仿真&#xff0c;差點意思&#xff0c;搞過嵌入式的應該有一個共識&#xff0c;是騾子是馬&#xff0c;你得把板子點亮啊。MinnowBoard MAX單板是intel10多年前發布的軟硬件全部…

AI Transformers 架構體系 權重文件類型 safeterson和gguf格式轉換【2-1】

模型權重文件&#xff1a;存儲訓練好的模型參數,也就是w和b&#xff0c;是模型推理和微調的基礎 .pt、.ckpt、.safetensors、gguf 配置文件&#xff1a;確保模型架構的一致性&#xff0c;使得權重文件能夠正確加載 config.json、generation_config.json 詞匯表文件&#xff1a;…

K8S微服務部署及模擬故障觀測

概述 本文介紹了如何在 Kubernetes (K8S) 集群中部署微服務&#xff0c;并模擬常見的故障場景&#xff08;如 Pod 故障、節點故障、網絡故障&#xff09;以測試系統的容錯能力。通過本實驗&#xff0c;了解 Kubernetes 的自動恢復機制以及如何通過監控和日志分析快速定位和解決…