自定义注解+拦截器实现,对部分敏感字段的加解密

news2025/1/11 2:21:42

上一篇,我用的自定义注解+AOP的方式,实现敏感字段的加解密,这一篇换个方案,这个方案相比一个方案,节省了一部分的性能开销

第一步:新建自定义注解

/**
 * 敏感信息类注解
 */
@Inherited
@Target({ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
public @interface EnableSensitive {
    boolean value() default true;
}
/**
 * 敏感字段注解
 */
@Inherited
@Target({ElementType.FIELD})
@Retention(RetentionPolicy.RUNTIME)
public @interface SensitiveFiled {
    String value() default "";
}

第二步:创建加密实现类

@Component
@Intercepts({
        //@Signature注解定义拦截器的实际类型
        @Signature(type = ParameterHandler.class, method = "setParameters", args = PreparedStatement.class)
})
public class EncryptInterceptor implements Interceptor {

    @Resource
    private SensitiveInfoService sensitiveInfoService;

    @Override
    public Object intercept(Invocation invocation) throws Throwable {
        // 取出请求参数
        ParameterHandler parameterHandler = (ParameterHandler) invocation.getTarget();
        Object parameterObject = parameterHandler.getParameterObject();
        // 如果参数不为空,并且是MapperMethod.ParamMap类型
        if (parameterObject instanceof MapperMethod.ParamMap) {
            Map<String, ?> paramMap = (MapperMethod.ParamMap) parameterObject;
            // 遍历请求参数,对敏感信息字段加密
            paramMap.forEach((k, v) -> {
                // 参数不为空,并且不是mybatis默认参数名
                if (null != paramMap.get(k)) {
                    Object param = paramMap.get(k);
                    EnableSensitive enableSensitive = AnnotationUtils.findAnnotation(param.getClass(), EnableSensitive.class);
                    if (null != enableSensitive && enableSensitive.value()) {
                        // 对敏感信息类中的敏感信息字段加密
                        sensitiveInfoService.encrypt(param);
                    }
                }
            });
        }
        return invocation.proceed();
    }

    /**
     * 加入此拦截器到拦截器链
     */
    @Override
    public Object plugin(Object target) {
        return Plugin.wrap(target, this);
    }
}

代码注释:
这段代码的功能是实现一个名为EncryptInterceptor的类,用作MyBatis的拦截器,主要对数据库操作中的敏感信息字段进行加密处理。具体功能如下:

  1. 依赖注入:通过@Resource注解,注入SensitiveInfoService服务,用于敏感信息的加密处理。
  2. 拦截器实现:实现Interceptor接口,对指定的方法进行拦截。此处拦截的是ParameterHandler类的setParameters方法,该方法负责设置PreparedStatement的参数。
  3. 参数获取与判断:在intercept方法中,获取ParameterHandler的参数对象。如果参数对象不为空且为MapperMethod.ParamMap类型(即Mapper接口方法的参数被封装成Map形式),则进行后续处理。
  4. 敏感信息加密:遍历参数Map,对每个非空参数值,检查其类上是否标注了@EnableSensitive注解且值为true。如果满足条件,调用sensitiveInfoService的encrypt方法对该参数的敏感字段进行加密。
  5. 执行流程控制:完成加密处理后,通过invocation.proceed()继续执行被拦截的方法,即ParameterHandler的setParameters方法。
  6. 插件机制:通过plugin方法,利用MyBatis的插件机制,将此拦截器加入到MyBatis的拦截器链中,从而对指定的目标对象进行增强处理。
    综上所述,EncryptInterceptor的主要作用是在MyBatis执行SQL之前,拦截并加密Mapper方法中的敏感信息字段,确保敏感数据的安全性。

第三步:创建解密实现类

@Component
@Intercepts({
        @Signature(type = ResultSetHandler.class, method = "handleResultSets", args = {Statement.class})
})
public class DecryptInterceptor implements Interceptor {

    @Resource
    private SensitiveInfoService sensitiveInfoService;

    @Override
    public Object intercept(Invocation invocation) throws Throwable {
        //取出查询的结果
        Object resultObject = invocation.proceed();
        if (null != resultObject) {
            // 校验是否需要解密,并对敏感信息进行解密
            sensitiveInfoService.decrypt(resultObject);
        }
        return resultObject;
    }

    /**
     * 加入此拦截器到拦截器链
     */
    @Override
    public Object plugin(Object target) {
        return Plugin.wrap(target, this);
    }
}

代码注释:
这段代码定义了一个名为DecryptInterceptor的拦截器类,用于在查询数据库后对结果进行解密。该拦截器通过@Component和@Intercepts注解标记,指定了它将拦截ResultSetHandler类中的handleResultSets方法,该方法接受一个Statement类参数。
主要功能包括:

  1. 拦截查询结果:在intercept方法中,拦截器取出查询的结果对象。
  2. 解密敏感信息:利用注入的SensitiveInfoService服务,检查查询结果是否需要解密,并对包含的敏感信息执行解密操作。
  3. 返回解密后的结果:最后,将处理后的结果返回。

此外,plugin方法用于将此拦截器加入到拦截器链中,使用Plugin.wrap方法包装目标对象。

示例:
在这里插入图片描述

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

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

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

相关文章

tomcat session共享

1. 日志监控工具 安装 tar xf goaccess-1.4.tar.gz cd goaccess-1.4/ yum install GeoIP-devel-1.5.0-13.el7.x86_64.rpm yum install -y ncurses-devel.x86_64 ./configure --enable-utf8 --enable-geoiplegacy make make install2. 使用 goaccess /usr/local/nginx/logs/a…

java多线程(六)关键字Volatile可见性、有序性以及单个变量的原子性

volatile关键字 作用 volatile 是 Java 虚拟机提供的轻量级的同步机制&#xff0c;主要用来确保变量被线程安全地读取和写入。 当一个变量定义为 volatile 后&#xff0c;它具备以下特性&#xff1a; 可见性&#xff1a;确保不同线程对这个变量操作的可见性&#xff0c;即一…

自存实践本地访问 nginx放前端打包好的项目

nginx 部署前端项目_哔哩哔哩_bilibili 将打包好的dits文件放到 配置nginx.conf文件的location 启动命令 start nginx.exe 输入localhost即可访问打包好的项目 nginx的特点 1.静态资源 2.转发 设置代理转发请求 关闭nginx .\nginx.exe -s quit

Kubernetes-Pod调度基础

一.复制控制器&#xff08;ReplicationController&#xff0c;RC&#xff09; RC用来确保Pod副本数达到预期值&#xff0c;这样可以确保一个或多个同类Pod总是可用的。可以通过扩缩来增加或减少pod。 &#xff08;1&#xff09;示例&#xff1a; vim replicationcontroller-ng…

Codeforces Round 967 (Div. 2)

文章目录 A. Make All Equal题目描述思路代码 B. Generate Permutation题目描述思路代码 C. Guess The Tree题目描述思路代码 A. Make All Equal 题目描述 一个数组&#xff0c;最多实行n-1次&#xff0c;计算最少多少次可以变为同一个数 思路 计算重复次数最多的数&#x…

产业园区数字化转型:面对挑战,我们如何把握机遇加速前行?

在当今数字化的时代浪潮中&#xff0c;产业园区数字化转型已成为推动经济发展和提升竞争力的关键举措。然而&#xff0c;这一进程并非坦途&#xff0c;充满了各种挑战。 产业园区数字化转型面临着技术更新换代快的压力。新技术不断涌现&#xff0c;如物联网、人工智能、大数据…

Mybatis 速通秘籍 节省回顾知识点和学习成本

目录 一、MyBatis简介 1、MyBatis历史 2、MyBatis特性 3、MyBatis下载 4、和其它持久层技术对比 二、搭建MyBatis 1、开发环境 2、创建maven工程 a>打包方式 b>引入依赖 3、创建MyBatis的核心配置文件 4、创建mapper接口 5、创建MyBatis的映射文件 6、通过j…

python学习之路 - python的异常、模块与包

目录 一、python的异常、模块与包1、了解异常2、异常的捕获方法a、捕获基本异常b、捕获指定异常c、捕获多个异常d、捕获异常后的finally 3、异常的传递4、python模块a、定义b、基础语法c、使用方法d、补充 5、python包a、定义b、操作方法c、使用方法 6、安装第三方python包a、命…

MVC和三层架构

&#x1f449;参考文章&#xff1a;mvc简介&#xff0c;mvc与三层架构的区别 一.MVC是什么&#xff1f; Model-View-Controller&#xff08;MVC&#xff09;是一种软件架构模式&#xff0c;是软件设计模式的体现 &#xff0c;用于组织代码并分离关注点&#xff0c;广泛应用于…

GPS和桩号互转

文章目录 前言一、通过bigmap软件生成坐标信息csv二、Java实现1.CSV分隔2.计算2.1 读取gps_data.csv2.2 读取piles.csv2.3 进行线性插值2.4 返回值实体2.5 根据GPS坐标计算距离工具2.6 根据GPS坐标读取桩号2.7 根据桩号读取GPS坐标(根据距离计算&#xff0c;找到最近的桩号) 前…

短视频SDK解决方案,智能技术加持,提升创作效率

随着社交媒体、直播电商、在线教育等领域的蓬勃发展&#xff0c;短视频以其独特的魅力迅速崛起&#xff0c;成为内容创作与传播的新风口。为了助力企业和个人轻松拥抱视频化趋势&#xff0c;美摄科技匠心打造了一套高效、易用的短视频SDK解决方案&#xff0c;以“轻编辑&#x…

【高级IO-2】IO多路转接之Select(概念及代码实例)

文章目录 I/O 多路转接 之 Select1. 了解select2. select 函数原型① fd_set 结构② 详细理解参数&#xff08;readfds为例&#xff09; 3. 理解select的执行过程4. select代码实例&#xff1a;监视多个文件描述符5. Socket就绪条件6. select代码实例&#xff1a;多路复用服务器…

每日掌握一个科研插图·2D密度图|24-08-21

小罗碎碎念 在统计学和数据可视化领域&#xff0c;探索两个定量变量之间的关系是一种常见的需求。为了更深入地理解这种关系&#xff0c;我们可以使用多种图形表示方法&#xff0c;这些方法在本质上是对传统图形的扩展和变体。 散点图&#xff1a;这是最基本的图形&#xff0c…

什么是 JavaConfig?

什么是 JavaConfig&#xff1f; &#x1f496;The Begin&#x1f496;点点关注&#xff0c;收藏不迷路&#x1f496; JavaConfig是Spring框架的一项创新&#xff0c;它允许开发者使用纯Java代码来配置Spring IoC容器&#xff0c;从而避免了繁琐的XML配置。这一特性带来了诸多优…

【微信小程序】导入项目

1.在微信开发工具中&#xff0c;点击【导入项目】 2.在打开的界面中执行2个步骤 1.找到要导入项目的路径2.AppID要改成自己的AppID 3.package.json包初始化【装包之前要确保有package.json文件】 1.在【资源管理器】空白处&#xff0c;点击鼠标右键&#xff0c;选择【】&am…

免费的真是太香了!Chainlit接入抖音 Coze AI知识库接口快速实现自定义用户聊天界面

前言 由于Coze 只提供了一个分享用的网页应用&#xff0c;网页访问地址没法自定义&#xff0c;虽然可以接入NextWeb/ChatGPT web/open webui等开源应用。但是如果我们想直接给客户应用&#xff0c;还需要客户去设置配置&#xff0c;里面还有很多我们不想展示给客户的东西怎么办…

[Python可视化]空气污染物浓度地图可视化

[Python可视化]空气污染物浓度地图可视化&#xff0c;果然是路边浓度最大 在本篇文章中&#xff0c;我将展示如何使用 Python 结合 OSMnx、NetworkX 和 GeoPandas 等库&#xff0c;计算给定路径的最短路线&#xff0c;并基于该路径穿过的网格单元计算总污染量。最终&#xff0c…

uniapp 修复使用 uni.saveImageToPhotosAlbum 方法在部分安卓手机上保存失败

场景&#xff1a;使用 uni.saveImageToPhotosAlbum 保存图片&#xff0c;其他手机都是可以的&#xff0c;但在鸿蒙系统的手机上出现了bug&#xff0c;报错Object {errMsg:"savelmageToPhotosAlbum:fai..errMsg:savelmageToPhotosAlbum:fail invalid filetype"} 原因&…

数学建模学习(116):全面解析梯度下降算法及其在机器学习中的应用与优化

文章目录 1.梯度下降简介1.1 梯度下降的数学原理1.2 学习率的选择2 梯度下降变体3.梯度下降优化器3.1 动量法(Momentum)3.2 AdaGrad3.3 RMSprop3.4 Adam3.5 Python 使用不同优化器训练线性回归模型4.案例:使用梯度下降优化加利福尼亚房价预测模型4.1. 数据准备4.2. 模型训练…

【dotnet】Ubuntu 24.04安装dotnet 8.0报错

我的环境是Ubuntu 24.04&#xff0c;64位&#xff0c;使用azure的虚拟机。 报错文字如下&#xff1a; kidfuazurefu:~$ sudo apt install dotnet-sdk-8.0 Reading package lists... Done Building dependency tree... Done Reading state information... Done Some packages c…