SpringBoot 使用【AOP 切面+注解】实现在请求调用 Controller 方法前修改请求参数和在结果返回之前修改返回结果

这篇具有很好参考价值的文章主要介绍了SpringBoot 使用【AOP 切面+注解】实现在请求调用 Controller 方法前修改请求参数和在结果返回之前修改返回结果。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

前情提要

在项目中需要实现 在请求调用 Controller 方法前修改请求参数和在结果返回之前修改返回结果

我们可以使用 AOP 切面+注解的形式实现。这样我们就可以在不修改原始代码的情况下,通过切面类在方法调用前后插入额外的逻辑。

解决方案

自定义注解 @PreProcess

自定义注解 @PreProcess 用于标记需要在方法调用前进行预处理的方法,以便后续处理。

@Target(ElementType.METHOD) // 表示该注解只能应用在方法上
@Retention(RetentionPolicy.RUNTIME) // 表示该注解在运行时仍然可用
public @interface PreProcess {
    // 可以添加其他注解属性的注释
}

自定义切面类 ModifiyAspect

接下来我们需要创建一个切面类,用于实现对带有自定义 @PreProcess 注解的方法进行处理。切面类代码如下:

/**
 * 用于对带有 @PreProcess 注解的方法进行处理的切面类。
 */
@Aspect // 表示该类是切面类
@Component // 表示该类为 Spring 组件
@Order(1001) // 表示该切面类的优先级为 1001
public class ModifiyAspect {

    /**
     * 定义切入点,用于匹配带有 @PreProcess 注解的方法。
     */
    @Pointcut("@annotation(com.example.demo.demos.annotation.PreProcess)")
    public void preProcess() {
    }

    /**
     * 在方法调用后进行处理,修改返回结果。
     * @param joinPoint 连接点对象
     * @return 修改后的返回结果
     * @throws Throwable 异常
     */
    @Around("preProcess()")
    public Object modifyResult(ProceedingJoinPoint joinPoint) throws Throwable {

        // 1.获取方法返回结果
        Object result = joinPoint.proceed();

        // 2.修改返回结果
        JSONObject jsonObject = JSONObject.parseObject(JSON.toJSONString(result));
        jsonObject.put("aspect", "aspect");
        
        // 3.返回修改后的结果
        result = jsonObject;
        return result;
    }

    /**
     * 在方法调用前进行处理,修改请求参数。
     * @param joinPoint 连接点对象
     * @return 修改后的返回结果
     * @throws Throwable 异常
     */
    @Around("preProcess()")
    public Object modifyParam(ProceedingJoinPoint joinPoint) throws Throwable {

        // 1.获取请求参数
        Object[] args = joinPoint.getArgs();
        Object arg = args[0];
        
        // 2.修改请求参数
        JSONObject jsonData = JSONObject.parseObject(JSON.toJSONString(arg));
        jsonData.put("test", "test");

        // 3.返回修改后的请求参数
        args[0] = JSONObject.parse(JSON.toJSONString(jsonData));
        return  joinPoint.proceed(args);
    }

}

在这个切面类中,通过对方法调用前后的处理,实现了对返回结果和请求参数的修改。

该类具体包含以下几个部分:

  1. 类注解:

    • @Aspect:表示该类是一个切面类,用于声明该类中包含了切面逻辑。
    • @Component:表示该类是 Spring 组件,用于让 Spring 容器自动扫描和管理该类。
    • @Order:表示该切面类的优先级,用于指定组件的加载顺序或切面的执行顺序,优先级高的切面类将先被执行,数值越小,优先级越高,默认值为 Integer.MAX_VALUE
  2. 方法注解:

    • @Pointcut:定义切入点,即匹配带有 @PreProcess 注解的方法。
    • @Around:表示该方法是一个环绕通知,在方法调用前后都会执行。
  3. 方法:

    • modifyResult() 方法在方法调用后,将返回结果转换为 JSON 对象,并添加一个名为 “aspect” 的属性,表示该返回结果是由该切面类修改的。

    • modifParam() 方法在方法调用前,将传入的请求参数转换为 JSON 对象,并添加一个名为 “test” 的属性,表示该请求参数是由该切面类修改的。

注:

joinPoint.getArgs() 方法返回一个 Object[] 数组,其中包含了方法调用时传入的所有参数。

这里假设方法调用时至少传入了一个参数,并且只取第一个参数进行处理。因此通过 args[0] 可以获取到第一个参数(索引为0)。

如果方法调用时没有传入参数,或者需要处理多个参数,可以根据实际情况进行修改。

编写 Controller 测试

创建两个接口,同样的逻辑,接收一个请求体参数 params,再将接收的参数以 JSON 格式返回:

@RestController
public class BasicController {

    /**
     * 处理 /hello 请求的方法
     * @param params 请求体参数,以键值对的形式传递
     * @return 经过转换后的 JSONObject 对象
     */
    @PreProcess
    @PostMapping("/hello")
    public JSONObject hello(@RequestBody Map<String, Object> params) {
        return JSONObject.parseObject(JSON.toJSONString(params));
    }

    @PostMapping("/hello1")
    public JSONObject hello1(@RequestBody Map<String,Object> params) {
        return JSONObject.parseObject(JSON.toJSONString(params));
    }
}

启动项目,在 ApiFox 中分别以同样的请求参数发送 POST 请求调用 /hello/hello1 接口:

  • 请求参数:

    {
        "name": "hello",
        "age": 20
    }
    
  • /hello 接口返回结果:

    {
        "test": "test",
        "aspect": "aspect",
        "name": "hello",
        "age": 20
    }
    
  • /hello1 接口返回结果:

    {
        "name": "hello",
        "age": 20
    }
    

复制多个 ModifiyAspect 切面模拟多切面同时修改请求体参数和返回结果,使用@Order注解指定执行顺序,测试结果如下:文章来源地址https://www.toymoban.com/news/detail-841891.html

{
    "test2": "test2",	//切面二
    "test": "test",	//切面一
    "aspect": "aspect",	//切面一
    "name": "hello",
    "aspect2": "aspect2",	//切面二
    "age": 20
}

到了这里,关于SpringBoot 使用【AOP 切面+注解】实现在请求调用 Controller 方法前修改请求参数和在结果返回之前修改返回结果的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • 如何将重复方法封装为Aop切面并结合注解使用

    首先要导入依赖 编写注解 编写Aop 方法上添加注解   然后测试就发现添加代码的方法都可以防止重复提交了!!

    2024年02月02日
    浏览(39)
  • 【Spring】javaBean、依赖注入、面向切面AOP、使用注解开发

    有一定规范的Java实体类,类内提供了一些公共方法以便外界对该对象的内部属性进行操作 所有属性都是private,所有的属性都可以通过get/set方法进行访问,同时还需要有一个无参构造(默认就有) 高内聚,低耦合是现代软件的开发的设计模式 之前编写的图书管理系统具有高

    2024年02月08日
    浏览(40)
  • Spring Boot学习随笔- 实现AOP(JoinPoint、ProceedingJoinPoint、自定义注解类实现切面)

    学习视频:【编程不良人】2021年SpringBoot最新最全教程 问题 现有业务层开发存在问题 额外功能代码存在大量冗余 每个方法都需要书写一遍额外功能代码不利于项目维护 Spring中的AOP AOP:Aspect 切面 + Oriented 面向 Programmaing 面向切面编程 Aspect(切面) = Advice(通知) + Pointcut(

    2024年02月04日
    浏览(33)
  • 【Spring】使用aop切面编程时要给那些类加注解

    🎄欢迎来到@边境矢梦°的csdn博文🎄  🎄本文主要梳理 Spring 中使用aop切面编程时要给那些类加注解 🎄 🌈我是边境矢梦°,一个正在为秋招和算法竞赛做准备的学生🌈 🎆喜欢的朋友可以关注一下 🫰🫰🫰 ,下次更新不迷路🎆 Ps: 月亮越亮说明知识点越重要 (重要性或者

    2024年02月07日
    浏览(37)
  • 【SpringBoot】常用的的各种注解(一):Controller中的请求参数

    请求路径中的参数,可以有一个或者多个 在Postman中也是直接在请求路径中添加参数即可 获取查询参数,形式为 url?name=张三 ,可以有一个或者多个。 在Postman中可以使用 Query Params 的方式添加参数: 也可以使用Body中的 form-data 的形式添加参数 一般用于传输DTO参数,只能有一

    2024年02月06日
    浏览(36)
  • 【数据脱敏方案】不使用 AOP + 注解,使用 SpringBoot+YAML 实现

    在项目中遇到一个需求,需要对交易接口返回结果中的指定字段进行脱敏操作,但又不能使用 AOP+注解 的形式,于是决定使用一种比较笨的方法: 首先将所有需要脱敏字段及其对应脱敏规则存储到 Map 中。 在接口返回时,遍历结果中的所有字段,判断字段名在 Map 中是否存在

    2024年03月15日
    浏览(77)
  • 1、springboot中使用AOP切面完成全局日志

    1、springboot中使用AOP切面完成全局日志 可选择在控制台输出日志或者收集日志信息存储进数据库中 1、在配置 AOP 切面之前,我们需要了解下 aspectj 相关注解的作用: @Aspect :作用是把当前类标识为一个切面、供容器读取 @Pointcut :(哪些方法或者类需要进行AOP织入)定义一个

    2024年02月02日
    浏览(25)
  • 注解 + spring aop切面+ SpringEl

    2024年02月09日
    浏览(30)
  • springboot3使用自定义注解+AOP+redis优雅实现防重复提交

      ⛰️个人主页:     蒾酒 🔥 系列专栏 :《spring boot实战》 🌊 山高路远,行路漫漫,终有归途 目录 写在前面 实现思路 实现步骤 1.定义防重复提交注解 2.编写一个切面去发现该注解然后执行防重复提交逻辑 3.测试 依赖条件 1.接口上标记防重复提交注解 2.接口测试 写在最

    2024年04月11日
    浏览(32)
  • SpringBoot简单使用切面类(@aspect注解)

    简介 Spring Boot中的AOP(Aspect Oriented Programming, 面向切面编程)可以让我们实现一些与业务逻辑无关的功能,如日志、事务、安全等。 特点 把这些跨切面关注点抽取出来,实现解耦。 使用切面承载这些功能的实现,而不污染业务逻辑。 在定义好的切入点Join Point,执行这些功能,比如方

    2024年02月10日
    浏览(31)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包