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.mzph.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 的自动恢复机制以及如何通过监控和日志分析快速定位和解决…