过滤器、拦截器、AOP、ControllerAdvcie的使用对比、执行顺序及代码教程

AOP实现对controller入参校验 之前leader交给我一个校验controller入参的任务,最终代码不太符合要求,被废弃,特此把代码记录下来,便于以后整理,提高。 先讲一下怎么用,目前版本只需要在需要校验的controller方法上添加@Validate注解,处理类中会自动识别String和bean,bean类型,需要在对应字段上添加@Require,才会对字段进行非空校验。 废话不多说,先贴代码(先写个初版,待有时间整理... 阅读详情

持续创作,加速成长!这是我参与「掘金日新计划 · 10 月更文挑战」的第12天,点击查看活动详情

前言

本文适合有一定基础的同学,在已有的认识基础上对这四块的知识做一个总体的对比。

本文基于SpringBoot项目进行讲解,所有的代码都是在已经搭好SpringBoot的基础上进行编写的,SpringBoot版本为2.7.3。

该项目所有的代码都已经上传到我的GitHub仓库:github.com/stick-i/Fil…

过滤器Filter

简介

  • 来自J2EE中的Servlet技术
  • 实现原理:基于servlet的函数回调实现
  • 只可以获取到请求中的request和response,无法获取到响应方法的信息
  • 可以拦截所有请求
  • 支持使用xml配置和注解配置
  • 应用场景:权限认证、敏感词检测、访问日志记录等

使用方法

  1. 实现 Filter 接口,重写 doFilter 方法;

  2. 放行请求时调用chain.doFilter()方法;

  3. 启用该过滤器,有三种方式,一种是比较原始的xml配置,这我就不写了,需要的同学请查看其它人的文章。

    第二种是使用注解 @WebFilter() ,并在启动类上添加@ServletComponentScan注解使用。

    第三种是直接使用@Component注解,这样的话@WebFilter配置的路径会失效,因为@WebFilter根本就没生效,不信自己去试试😘。

    下面我使用的是第二种方式,更灵活

  4. 设置拦截路径,就是要拦截的那个url路径。

代码实现

过滤器代码

@Slf4j
@WebFilter(value = "/name") //这里我们只拦截name请求,记得要在启动类配ServletComponentScan
public class MyFilter implements Filter {

	@Override
	public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws ServletException, IOException {
		log.info("before filter");
		// 请求放行
		chain.doFilter(request, response);
		log.info("after filter");
	}

}
复制代码

Controller代码

@Slf4j
@RestController
public class MyController {

	@GetMapping("/name")
	public String getName() {
		log.info("getName");
		return "sticki";
	}

}
复制代码

测试

发送请求

image-20220904165711234

查看控制台,可以观察到执行的顺序是按照我们代码中的前后顺序来执行的。

image-20220904165724961

拦截器Interceptor

简介

  • 来自Spring,不依赖于servlet容器,但依赖于Spring

  • 实现原理:通过反射机制,动态代理实现

  • 可以获取到Spring中存在的Bean,通过注入的方式

  • 只对action请求起作用,并可以获取到action请求的上下文

  • 应用场景:访问日志、权限管理等(场景这块感觉跟过滤器差不多)

使用方法

  1. 实现 HandlerInterceptor 接口 或 继承 HandlerInterceptorAdapter 类,建议使用接口;
  2. 实现 preHandle 方法(在处理请求前运行),实现 postHandle 方法(在处理请求完毕后运行);
  3. 再新建一个类,继承 WebMvcConfigurer 接口,再实现addInterceptors方法,并在方法中注册该拦截器、配置拦截路径(不配置默认拦截所有请求);

代码实现

拦截器代码

@Slf4j
public class MyInterceptor implements HandlerInterceptor {

	@Override
	public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) {
		log.info("before interceptor");
		return true;
	}

	@Override
	public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) {
		log.info("after interceptor");
	}

}
复制代码

配置类代码

@Configuration
public class InterceptorConfig implements WebMvcConfigurer {

	@Override
	public void addInterceptors(InterceptorRegistry registry) {
        // 只拦截 age 的请求
		registry.addInterceptor(new MyInterceptor()).addPathPatterns("/age");
	}

}
复制代码

Controller代码,还是刚刚那个Controller,不过我添加了一个新的请求 /age

@GetMapping("/age")
	public Integer getAge() {
		log.info("getAge");
		return 22;
	}
复制代码

测试

发送请求

image-20220904173656645

查看控制台

image-20220905180442971

ControllerAdvice

简介

  • 来自Spring,依赖于Spring
  • 应用场景:全局异常处理(配合自定义异常效果更佳)、数据绑定、数据预处理
  • 可以使用注解@ControllerAdvice,实现 ResponseBodyAdvice、RequestBodyAdvice 等接口,用于web项目的返回数据加强。

image-20220830164607108

使用方法

  1. 创建一个类,给类加上注解@RestControllerAdvice
  2. 写一个方法,给方法加上注解 @ExceptionHandler(Exception.class) ,括号里写要拦截的异常,方法的参数也是这个异常或者这个异常的父类
  3. 在方法中写对该异常的处理

ps:这里我只写了全局异常处理的代码,需要的同学可以去查一查其他的使用方法噢,也可以看一下这个:www.cnblogs.com/tiancai/p/1… ,写的挺全的。

代码实现

ControllerAdvice

@Slf4j
@RestControllerAdvice
public class ExceptionAdvice {

	@ExceptionHandler(Exception.class)
	public String allExceptionHandler(Exception e) {
		log.warn(e.getMessage()); // 捕获之后打印异常信息
		return "系统异常,请稍后再试";
	}

}
复制代码

Controller代码,也是新加了一个请求 /exception

@GetMapping("/exception")
	public String getException() {
		log.info("getException");
		throw new RuntimeException("报错啦");
	}
复制代码

测试

发送请求,可以看到这里的信息是返回的 ControllerAdvice 里面的,而不是Controller里面的。

image-20220904231333908

查看控制台

image-20220904234653090

AOP

简介

  • AOP是一种面向切面编程的实现,实现的方式还挺多的,有SpringAOP,也有AspectJ、CGLIB等
  • 实现原理:基于动态代理或静态代理
  • 细粒度的拦截,可以获取到切入方法的参数等上下文数据,配合注解使用非常的舒服
  • 应用场景:一般用于方法的加强,比如方法级别的权限控制、日志输出、读取写入缓存、方法调用次数限制等

使用方法

  1. 创建一个类,给类加上@Aspect 和 @Component注解
  2. 定义切入点 @Pointcut() ,可以定义在注解上(使用注解的类或方法即切入点),也可以直接指定切入的范围
  3. 根据需要定义 @Before("pointcut()") 和 @After("pointcut()"),然后在内部写处理逻辑

ps:这里我只写了spring aop的使用,需要的同学自己去百度找其他的使用方法噢

代码实现

AOP代码

@Slf4j
@Aspect
@Component
public class MyAop {

	/**
	 * 仅匹配getAop这一个方法
	 */
	@Pointcut("execution(* cn.sticki.test.controller.MyController.getAop())")
	public void pointcut() {

	}

	@Before("pointcut()")
	public void before() {
		log.info("aop before");
	}

	@After("pointcut()")
	public void after() {
		log.info("aop after");
	}

}
复制代码

最左边会有个小符号😎

image-20220905175450239

Controller代码,添加一个新的方法

@GetMapping("/aop")
	public String getAop() {
		log.info("getAop");
		return "aop";
	}
复制代码

测试

发送请求

image-20220904234414824

查看控制台

image-20220904234611152

完全没问题😋

四者的执行顺序

好,既然我们四个都写完了,那就再加一点东西,让他们四个同时处理到一个方法上,那我们就可以测试出四者的执行顺序了🤣。

添加了几个方法,这里直接给大家截图了,需要的同学可以去仓库拿代码。

Controller代码

image-20220905175702786

AOP代码

image-20220905175537324

Filter配置加了一条

image-20220905175742542

Interceptor配置也加一条

image-20220905180230039

最后Advice是不用加的


准备完毕,然后就可以去测试了。

发送请求:

image-20220905180111774

控制台:

image-20220905180525131

结论

可以看到,执行顺序是:Filter过滤器 > Interceptor拦截器 > ControllerAdvice > AOP。

解释:Filter和Interceptor的执行顺序是可以直接看出来的,AOP、ControllerAdvice 的执行顺序得看getAll的后面,getAll是controller输出的内容嘛,它的下一条是aop,然后才是异常被捕获,反方向先执行,说明 ControllerAdvice 是在 AOP 外面一层的。

这里也可以看出来,当抛出的异常被 ControllerAdvice 捕获之后, Interceptor 拦截器不会再有后置处理了,但是Filter过滤器还是有后置处理的。

这里画了张图便于大家理解:

image-20220905192606129

总结

这四者其实都是面向切面编程思想的一种实现。具体使用选择的话建议根据项目需要,参考它们的特性及执行顺序,选择最合适的一个或多个进行使用👴。

来源:https://juejin.cn/post/7153055158610427934
优雅处理HTTP请求:过滤器拦截器、ControllerAdvice和自定义AOP 在Spring Boot项目中,可以使用自定义AOP的方式来统一处理HTTP请求,并获取和解析请求头中的内容。通过自定义AOP切面,可以在请求处理前和处理后添加相应的切面逻辑。以下例子展示如何在Spring Boot项目中实现自定义AOP切面来获取和解析请求头中的内容:创建一个注解,用于标注需要进行切面处理的方法。在该注解中添加一个String类型的属性,用于指定需要获取的请求头信息。java复制代码Java复制代码@Retention(RetentionPolicy.RUNTIME) 阅读详情

相关推荐

使用AOP优化Spring Boot Controller参数:自动填充常用字段的技巧

本篇博客将深入介绍如何利用AOP技术,在Spring Boot应用中实现对Controller保存方法参数的重写。我们将重点讨论如何利用AOP切面,自动填充常用字段(如创建时间、修改时间、创建人、修改人),以提高代码的重用性和可维护性。

todoitbo的博客 1万+

SpringBoot--过滤器/拦截器/AOP--区别/使用/顺序

本文介绍SpringMVC(SpringBoot)中的过滤器、拦截器、AOP的区别及其用法。 如果监听器、过滤器、拦截器、AOP都存在,则它们的执行顺序为:监听器 => 过滤器=> 拦截器=> AOP。

IT利刃出鞘的博客 9336

SiC MOSFET驱动设计实战:从特性解析到电路优化

本文深入解析SiC MOSFET的核心特性及其驱动电路设计要点,涵盖高温稳定性、快速开关能力等关键特性,并提供驱动电压配置、电流能力计算、布局优化等实用方案。特别针对第三代电力电子半导体SiC MOSFET的驱动要求,分享STGAP1AS等典型驱动方案的应用技巧,助力工程师解决高频应用中的EMI和热管理挑战。

weixin_29230865的博客 365

过滤器、拦截器、aop的 先后顺序和作用范围

在Spring框架中,过滤器(Filter)、拦截器(Interceptor)和面向切面编程(AOP)都是用于处理请求和处理流程的组件,但它们的作用范围和触发时机有所不同。下面我会解释这三者的先后顺序和作用范围。请注意,这个顺序可能因具体的配置和使用的技术而有所不同。在实际应用中,建议根据项目的具体需求来合理配置和使用这些组件。

weixin_43784341的博客 832

多目标优化权衡分析:从 Pareto 前沿到 3 种量化指标(相关系数/膝点/理想点)

本文深入探讨多目标优化中的权衡分析,介绍从Pareto前沿到三种量化指标(相关系数、膝点、理想点)的实用方法。通过Python代码示例和对比分析,帮助读者在工程设计、投资组合等场景中有效评估目标间的Trade-off关系,实现科学决策。

weixin_29032337的博客 393

【深度学习】手把手教你在远程服务器上跑 YOLOv3 相关代码(含环境配置)

这篇文章主要记录了如何配置项目环境以及如何在远程服务器上跑 YOLOv3 模型。

作者正在煮茶中... 2383

过滤器、拦截器、AOP、ControllerAdvcie执行顺序对比

来自J2EE中的Servlet技术实现原理:基于servlet的函数回调实现只可以获取到请求中的request和response,无法获取到响应方法的信息可以拦截所有请求支持使用xml配置和注解配置应用场景:权限认证、敏感词检测、访问日志记录等来自Spring,不依赖于servlet容器,但依赖于Spring实现原理:通过反射机制,动态代理实现可以获取到Spring中存在的Bean,通过注入的方式只对action请求起作用,并可以获取到action请求的上下文。

zhangjunli的博客 1389

jmeter5.4.1 使用案例

jmeter主要用于接口压力测试,模拟海量请求并发访问接口 1.下载jmeter https://jmeter.apache.org/download_jmeter.cgi 2.启动jemter 双击即可 3.配置jmeter 1.先更改语言 2.创建线程组 配置线程执行规划 3.创建http请求默认值 4.创建http请求 5.创建http信息头管理器 指定 Content-Type:application/json 6.创建响应断言 7.创建察看结果数 直接点击 执行 按.

SpringHASh的博客 1221

springMVC中拦截器执行时机和执行顺序分析

springMVC中在配置拦截器的时候,拦截器的每个方法在哪里执行?如果有多个拦截器,那么他们每个方法的执行顺序怎么判断

w55935的博客 6585

OpenHarmony v4.1 Release设置应用随系统自动启动

OpenHarmony 4.1 版本中的 Ability Manager Service (AMS) 提供了应用自启动管理功能,允许系统控制哪些应用可以在系统启动时自动运行。这需要以下两个主要步骤:启用系统的自启动管理支持开发一个系统应用来管理自启动配置。

afufufufu的博客 1899

livox avia平台搭建

livox雷达数据采集平台搭建

Shilong的博客 1310

调整多个ControllerAdvice的执行顺序

有时候在项目里面会有多个 @ControllerAdvice 或者 @RestControllerAdvice 的情况,这时候,可能就会出现一个特定的异常被其他的处理掉,从而出现一些奇怪的问题。

felixu的博客 1万+

Windows 11 安装 Miniconda + Mamba,配置国内源

本文详细介绍了在 Windows 11 系统下安装 Miniconda 并配置 Mamba 的完整流程,包括选择精简版 Miniconda 的理由、安装过程中的关键选项设置、配置清华大学镜像源以加速包下载,以及在 base 环境中设置 pip 国内源。同时说明了 Mamba 相较 Conda 的性能优势,并指导用户完成 Mamba 安装与 Shell 集成,最终通过命令验证环境管理功能,帮助用户构建高效、轻量的 Python 开发环境。

寒水馨 · 轻量级技术文档 · hanshuixin.org 3345

@RestControllerAdvice中ExceptionHandler的执行顺序

1.先看异常是不是@ExceptionHandler中配置的 2.异常可能提示的是A异常,实际上捕捉的B异常,例如JsonParseExcepetion被捕捉,抛出的是HttpMessageNotReadableException异常 源码解析: AbstractHandlerExceptionResolver中调用resolveException方法 public ModelAndView resolveException(HttpServletRequest request, HttpServl

weixin_43941313的博客 2360

NVIDIA Isaac ROS - 入门教程(一)

欢迎访问 Isaac ROS,这是一套硬件加速、高性能、低延迟的 ROS 2 软件包,用于制造自主机器人,充分利用 Jetson 和其他英伟达平台的强大功能。英伟达 Jetson 平台运行在基于 Ubuntu Linux 的 JetPack 操作系统上。JetPack 5.x 是在 Ubuntu 20.04 Focal 的基础上构建的,这意味着由 ROS 2 Buildfarm 为 Ubuntu 22.04 Jammy 构建的 ROS 2 Humble 的 Debian 包不受支持。由于官方 ROS 2 B

机器人控制与仿真应用 5721

VC中sqlite的使用

在VC中对sqlite的使用,实现数据库大批数据的快速插入,读取数据库中的数据在ListCtrl中显示

Springboot 使用多个 @RestControllerAdvice 时的拦截顺序

controller异常拦截解决异常的方法有三种: 1、使用aop进行切面拦截异常 2、controller每个方法都用try-catch捕获异常 3、增加一个@RestControllerAdvice标注的类,负责处理我们项目的异常 一般放在一个类中就不会有这种情况了,而我用了两个类全局异常处理类和接口参数校验处理类 还有一种情况是一用力别人的模块,模块中是用了@RestControllerAdvice的类, 多个加了@RestControllerAdvice的类它们会按照类名依次加载,如果前面的类有能处

御剑长歌的博客 6210

TMS_WebGMaps_1.9.8.0_Full_Source

TMS_WebGMaps_1.9.8.0_Full_Source 全源码 delphi cbuilder

拦截器interceptor总结

拦截器是一种动态拦截方法调用的机制,在SpringMVC中动态拦截controller方法的执行;

机械工程跑路哥 6902

Data-Structures-and-Algorithm-Analysis-in-Java.pdf

作者: Weiss, Mark A. 出版社: Addison Wesley Data Structures and Algorithm Analysis in Java is an “advanced algorithms” book that fits between traditional CS2 and Algorithms Analysis courses. In the old ACM Curriculum Guidelines, this course was known as CS7. This text is for readers who want to learn good programming and algorithm analysis skills simultaneously so that they can develop such programs with the maximum amo...

蓝牙模块HM-10手册

蓝牙模块HM-10手册,该手册对蓝牙模块HM-10进行了详细的介绍和使用方法以及一些AT指令。

过滤器,拦截器,SpringAop执行顺序详解(基于Springboot2.0)

结论:能看懂就不用往下翻了,不过点个赞还是很nice的 ====doFilter==== ====preHandle==== =====around02 start==== ====before02===== =====around01 start==== ====before01===== ====method run==== =====around01 end====1 =====afte...

X_X_K的博客 1915

过滤器 拦截器 aop 的先后循序

在 Spring 框架中,过滤器、拦截器和 AOP(面向切面编程)是处理请求的三种机制,它们的执行顺序如下:

刘皇叔说Java的博客 816

SpringBoot 使用过滤器、拦截器、切面(AOP),及其之间的区别和执行顺序

Servlet(Server Applet),全称是Java Servlet,是提供基于协议请求/响应服务的Java类。在JavaEE中是Servlet规范,即是指Java语言实现的一个接口,广义的Servlet是指任何实现了这个Servlet接口的Java类,一般人们理解是后者。是什么。

qq_43842093的博客 3022

Aop监控所有Controller,包括void类型的response中的出参(工具类)

Aop监控所有Controller,包括void类型的response中的出参(工具类) response.getWriter().write();

qq_44299529的博客 880

同一个springboot项目中,统一异常处理有多个@RestControllerAdvice 时的拦截顺序

https://www.cnblogs.com/chongcheng/p/13058345.html

sensen的博客 1199

过滤器、拦截器、aop -> ‘三兄弟‘

6、拦截器可以获取IOC容器中的各个bean,而过滤器就不行,因为拦截器是spring提供并管理的,spring的功能可以被拦截器使用,在拦截器里注入一个service,可以调用业务逻辑。10、Filter的生命周期由Servlet容器管理,而拦截器则可以通过IoC容器来管理,因此可以通过注入等方式来获取其他Bean的实例,因此使用会更方便。8、Filter是依赖于Servlet容器,属于Servlet规范的一部分,而拦截器则是独立存在的,可以在任何情况下使用。1、过滤器,拦截器拦截的是URL。

Y_hahaha的博客 1952
上一篇: 如何快速过滤出一次请求的所有日志?
下一篇: Java 中 List 分片的 5 种方法!
码趣资源网
博客等级 码龄4年 268粉丝 518原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值