Java Spring 通过 AOP 实现方法参数的重新赋值、修改方法参数的取值

news2024/10/5 6:28:08

AOP 依赖

我创建的项目项目为 SpringBoot 项目

    <parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>3.1.3</version>
    </parent>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-aop</artifactId>
        </dependency>

String 类型参数

这里以对前端传递过来的加密数据进行解密为例

注解

import java.lang.annotation.*;

/**
 * 标注需要进行 RSA 加密算法解密的通用注解。
 * 该注解可以使用在类上、方法上、方法参数上、字段/属性上、局部变量上
 */
@Target({ElementType.TYPE, ElementType.METHOD, ElementType.PARAMETER, ElementType.FIELD, ElementType.LOCAL_VARIABLE})
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface DecodeRsaCommonAnnotation {
}
import java.lang.annotation.*;

/**
 * 标注需要进行 RSA 加密算法解密的方法参数的注解。
 * 该注解可以使用在方法参数上
 */
@Target({ElementType.PARAMETER})
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface DecodeRsaParameterAnnotation {
}

控制器方法

    @GetMapping("/test")
    @DecodeRsaCommonAnnotation
    public void test(
            @DecodeRsaParameterAnnotation
            String text
    ) {
        System.out.println(text);
    }

方式一:通过环绕通知实现 [个人比较推荐]

import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Pointcut;
import org.springframework.core.annotation.Order;
import org.springframework.stereotype.Component;

@Aspect
@Order(1)
@Component
public class DecodeRsaAspect {

    /**
     * DecodeRsaAspect 的切点为被 @DecodeRsaCommonAnnotation 标记的位置
     */
    @Pointcut("@annotation(cn.org.xiaoweiba.graduationdesign.bookmall.annotation.rsa.DecodeRsaCommonAnnotation)")
    public void pointCut() {
    }

    /**
     * 采用 Rsa 加密算法进行解密
     *
     * @param proceedingJoinPoint 切点
     */
    @Around("pointCut()")
    public Object decodeRsaAroundAdvice(ProceedingJoinPoint proceedingJoinPoint) {
        Object returnVal = null;
        try {
            // 获取切点方法的参数
            Object[] args = proceedingJoinPoint.getArgs();
            // 中间处理 ...
            // 对切点方法的参数进行重新赋值
            for (int i = 0; i < args.length; i++) {
                args[i] = "RSA 加密算法解密后的数据";
            }
            // 执行切点方法,并传递重新赋值后的参数列表
            returnVal = proceedingJoinPoint.proceed(args);
        } catch (Throwable e) {
            // 异常处理 ...
        }
        // 返回切点方法执行后的返回值
        return returnVal;
    }

}

在这里插入图片描述
在这里插入图片描述

方式二:通过前置通知 + 反射实现

Java ReflectUtil 反射相关的工具类

由于 JDK 8 中有关反射相关的功能自从 JDK 9 开始就已经被限制了,如:通过反射修改 String 类型变量的 value 字段(final byte[]),所以要能够使用运行此方法,需要在运行项目时,添加虚拟机(VM)选项:--add-opens java.base/java.lang=ALL-UNNAMED,开启默认不被允许的行为

通过反射修改 String 类型对象 value 取值的工具方法

获取指定对象中的指定字段(不包含父类中的字段)

    /**
     * 获取指定对象中的指定字段(不包含父类中的字段)。
     * 此方法在获取指定对象中的指定字段时,会包证获取的指定字段能够被访问。
     *
     * @param object 要获取字段的指定对象
     * @param fieldName 要获取的指定字段的名称
     * @return 指定对象中的指定字段
     */
    public static Field getField(Object object, String fieldName) throws NoSuchFieldException {
        // 获取指定对象的 Class
        Class<?> objectClass = object.getClass();
        // 获取指定对象中的指定字段
        Field declaredField = objectClass.getDeclaredField(fieldName);
        // 保证获取的指定字段能够被访问
        declaredField.setAccessible(true);
        return declaredField;
    }

通过反射为字符串对象的 value 字段重新赋值为 strValue

    /**
     * 通过反射为字符串对象的 value 字段重新赋值为 strValue,
     * 从而保证不修改字符串对象的引用,并且能够修改字符串的取值
     * 由于 JDK 8 中有关反射相关的功能自从 JDK 9 开始就已经被限制了,所以要能够使用运行此方法,
     * 需要在运行项目时,添加虚拟机(VM)选项:--add-opens java.base/java.lang=ALL-UNNAMED
     * 开启默认不被允许的行为
     *
     * @param str 需要进行重新赋值的字符串对象
     * @param strValue 要赋值给字符串对象的值
     */
    public static void setValueString(String str, String strValue) throws NoSuchFieldException, IllegalAccessException {
        // 获取字符串的 value 字段
        Field strValueField = getField(str, "value");
        // 为字符串对象的 value 字段重新赋值
        // strValueField.set(str, strValue.getBytes(StandardCharsets.UTF_8)); 不要使用该种方法,会出现乱码
        // 采用如下方式,获取 strValue 的 value 字段值,将其赋值给 str 的 value 字段
        strValueField.set(str, strValueField.get(strValue));
    }
切面类
import cn.org.xiaoweiba.graduationdesign.bookmall.utils.ReflectUtil;
import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;
import org.aspectj.lang.annotation.Pointcut;
import org.springframework.core.annotation.Order;
import org.springframework.stereotype.Component;

@Aspect
@Order(1)
@Component
public class DecodeRsaAspect {

    /**
     * DecodeRsaAspect 的切点为被 @DecodeRsaCommonAnnotation 标记的位置
     */
    @Pointcut("@annotation(cn.org.xiaoweiba.graduationdesign.bookmall.annotation.rsa.DecodeRsaCommonAnnotation)")
    public void pointCut() {
    }

    /**
     * 采用 Rsa 加密算法进行解密
     *
     * @param joinPoint 切点
     */
    @Before("pointCut()")
    public void decodeRsaBeforeAdvice(JoinPoint joinPoint) {
        try {
            // 获取切点方法的参数
            Object[] args = joinPoint.getArgs();
            // 中间处理 ...
            // 对切点方法的参数进行重新赋值
            for (int i = 0; i < args.length; i++) {
                // 对字符串对象的 value 字段重新赋值,不修改字符串对象的指向,保证修改的为切点方法的字符串对象参数
                ReflectUtil.setValueString((String) args[i], "解密后的数据");
            }
        } catch (Throwable e) {
            // 异常处理 ...
        }
    }

}

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1124661.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

Linux:【Kafka-Java一】Spring实现kafka消息的简单发送

目录 一、创建maven项目 二、引入依赖 三、创建生产者 一、创建maven项目 1.1、创建maven项目不再多说 二、引入依赖 1.1、maven项目创建完成后&#xff0c;需要引入以下依赖 // kafka 依赖<dependency><groupId>org.apache.kafka</groupId><artifact…

GRE MGRE原理与配置

IPSec VPN用于在两个端点之间提供安全的IP通信&#xff0c;但只能加密并传播单播数据无法加密和传输语音、视频、动态路由协议信息等组播数据流量。通用路由封装协议GRE( Generic Routing Encapsulation )提供了将一种协议的报文封装在另一种协议报文中的机制&#xff0c;是一种…

华为云全新上线Serverless应用中心,支持一键构建文生图应用

近日&#xff0c;华为云全新上线Serverless应用中心&#xff0c;提供了大量应用模板&#xff0c;让用户能够一键部署函数和周边依赖资源&#xff0c;节省部署时间&#xff0c;快速上手将应用部署到华为云函数计算FunctionGraph&#xff0c;并一键开通周边依赖资源。 本次Serve…

微信小程序ios页面没有滚动下拉也会出现黑色背景

问题截图&#xff1a; 查了一下资料说有用一下方法解决的&#xff1a; 整体overflow: hidden&#xff0c;页面的内容将无法滚动&#xff08;试了一下没用&#xff09;&#xff1b;设置 -webkit-overflow-scrolling 和 touch-action 样式属性来禁用页面的拖动和拉拽操作&…

底层驱动day4作业

分布注册设备&#xff0c;实现文件和设备的绑定 代码&#xff1a; //head.h #ifndef __HEAD_H__ #define __HEAD_H__ #define PHY_RCC 0x50000A28 #define PHY_GPIOE_MODER 0x50006000 #define PHY_GPIOF_MODER 0x50007000 #define PHY_GPIOE_ODR 0x50006014 #define PHY_GPI…

VR虚拟现实技术在法院技能培训中的应用

开展法治宣传教育&#xff0c;是全面贯彻落实科学发展观的重要决策&#xff0c;也是保障和促进经济设备会发展和实施“十一五”规划的内在要求。为了让全民法治文化宣传深入人们群众中&#xff0c;突破性地采用VR虚拟现实、web3d开发和三维仿真技术&#xff0c;开发线上法治文化…

Git的标签管理

Git标签管理 创建标签操作标签小结 创建标签 在Git中打标签非常简单&#xff0c;首先&#xff0c;切换到需要打标签的分支上&#xff1a; $ git branch $ git checkout master 然后&#xff0c;敲命令git tag 就可以打一个新标签&#xff1a; $ git tag v1.0 可以用命令git …

大一新生必备电脑软件插件有哪些?

毕业老学姐倾情分享珍藏必备软件和浏览器插件&#xff01;拥有后生活明朗&#xff0c;学习效率UPUP&#xff01; 纯干货分享建议【点赞收藏】后观看 速览 Office全家桶-Word、Excel、Powerpoint大学生必备 火绒安全-计算机防病毒软件 AI助手-AI对话写作阅读助手&#xff0c;…

HCIP-MGRE实验

实验拓扑图 需求 1 R5为ISP &#xff0c;只能进行IP地址配置;其所有地址均配为公有IP地址 2 R1和R5间使用PPP的PAP认证&#xff0c;R5为主认证方; R2于R5之间使用ppp的chap认证&#xff0c;R5为主认证方; R3于R5之间使用HDLC封装。 3 R1/R2/R3构建一个MGRE环境&#xff0c;R1为…

创新驱动|RFID技术在智能半导体行业的应用

半导体产业是我国重要的战略性新兴产业&#xff0c;是一个需要高度协同的领域&#xff0c;需要各个环节的紧密配合。RFID技术&#xff0c;作为一种自动识别和数据采集技术&#xff0c;在半导体生产线上具有独特的优势。通过应用RFID技术&#xff0c;半导体制造企业可以实现生产…

基于Python+Selenium+Unittest+PO设计模式

一、什么是PO设计模式&#xff08;Page Object Model&#xff09; 1、Page Object是一种设计模式&#xff0c;它主要体现在对界面交互细节的封装上&#xff0c;使测试用例更专注于业务的操作&#xff0c;从而提高测试用例的可维护性。 2、一般PO设计模式有三层 第一层&#x…

【鸿蒙软件开发】文本显示(Text/Span)

文章目录 前言一、Text控件1.1 创建文本string字符串引用Resource资源 1.2 添加子组件创建Span文本装饰线和样式文本装饰线设置文字一直保持大写/小写添加事件。 1.3 自定义文本样式文本对齐长文本处理设置行高通过decoration属性设置文本装饰线样式及其颜色。通过baselineOffs…

功率放大器在PZT陶瓷薄膜压电传感器研究中的应用

随着科技的进步和工业发展的需求&#xff0c;对于压力测量和控制的需求日益增加。压力传感器作为一种关键的传感器器件&#xff0c;在机械、自动化、医疗、航空等多个领域都有广泛应用。PZT陶瓷薄膜压电传感器由于其响应速度快、精度高、稳定性好等优点&#xff0c;成为了许多应…

OTA: Optimal Transport Assignment for Object Detection 论文和代码学习

OTA 原因步骤什么是最优传输策略标签分配的OT正标签分配负标签分配损失计算中心点距离保持稳定动态k的选取 整体流程代码使用 论文连接&#xff1a; 原因 1、全部按照一个策略如IOU来分配GT和Anchors不能得到全局最优&#xff0c;可能只能得到局部最优。 2、目前提出的ATSS和P…

做数据可视化,谨记三大要点

数据可视化报表就是“一图胜千言”的最佳例子。数据可视化&#xff0c;也就是将数据图形化、图表化&#xff0c;以良好的视觉效果呈现数据&#xff0c;达到发现、分析、预测、监控、决策等目的。要想做出一份优秀的数据可视化报表&#xff0c;那就要在做报表时谨记三大要点&…

3D模型在线格式转换工具

单模型上传格式 支持格式说明 支持RAR和ZIP压缩包上传&#xff0c;压缩包大小按原始文件大小计算&#xff0c;压缩包内只能包含一个模型文件 超过500MB的模型请联系客服 您也可以下载老子云客户端进行批量上传 不同会员级别的模型上传大小有不同的限制&#xff0c;详情请查询…

越来越好用的Edge浏览器,盘点Edge浏览器功能丨插件

前些年&#xff0c; Edge 浏览器也宣布加入 Chromium 内核&#xff1b;它的前身是IE浏览器&#xff0c; Edge之所以越来越多人用的一个原因是因为它的内核是Google Chrome的Chromium&#xff0c;而且不需要膜法就可以使用&#xff0c;这一点Chrome浏览器还不行&#xff0c;访问…

分拣设备运动仿真

这一次我们来分享一下如何在Solidworks 中做出传送台的分拣动作并通过分拣动作生成过程动画&#xff0c;以便于我们可以用于产品展示又或者验证运行程序无误的情况下结构是否会影响输送效率。 首先创建一个新的运动算例 将窗口切换至Motion分析 在设置之前我们先理清设置传送带…

税务某局 webpack 登录接口逆向分析

持续创作文章&#xff0c;只是为了更好的思考 这里不多介绍了&#xff0c;我放一张图大家就明白是什么接口了。这里只介绍整体加密逻辑&#xff0c;有些细的地方大家自行调整。 本次逆向的网址是 aHR0cHM6Ly90cGFzcy5qaWxpbi5jaGluYXRheC5nb3YuY246ODQ0My8jL2xvZ2luP3JlZGly…

vue3实现详情页返回列表页,返回原来列表页滚动条所在的位置

keepAlive缓存页面 组合式API 第一步第二步第三步第四步 第一步 首先在路由文件的meta里面定义 meta: {keepAlive: false, },第二步 在app.vue 根文件下定义代码 <template><keep-alive><router-view v-if"route.meta.keepAlive" /></keep-…