springboot3使用​自定义注解+Jackson优雅实现接口数据脱敏

 

⛰️个人主页:     蒾酒

🔥系列专栏:《spring boot实战》

🌊山高路远,行路漫漫,终有归途


目录

写在前面

内容简介

实现思路

实现步骤

1.自定义脱敏注解

2.编写脱敏策略枚举类

3.编写JSON序列化实现

4.编写测试类

5.编写测试接口

6.接口测试

写在最后


写在前面

本文介绍了springboot开发后端服务中,接口数据脱敏优雅的设计与实现,坚持看完相信对你有帮助。

同时欢迎订阅springboot系列专栏,持续分享spring boot的使用经验。

内容简介

本文介绍了一种以优雅的方式实现对接口返回的敏感数据,如手机号、邮箱、身份证等信息的脱敏处理。这种方法也是企业常用方法。话不多说我们一起来看一下吧。

效果展示:

实现思路

  • 自定义一个脱敏注解用于标记需要脱敏的字段,并且在注解中指定脱敏策略属性。
  • 自定义脱敏策略枚举类,用于维护手机号、邮箱、身份证等信息的脱敏处理方式。
  • 自定义脱敏 JSON 序列化器,在该序列化器中找到带有该注解的字段,根据注解中指定的脱敏策略,在序列化过程中将数据进行脱敏处理并输出到 JSON 中。

实现步骤

1.自定义脱敏注解


import com.fasterxml.jackson.annotation.JacksonAnnotationsInside;
import com.fasterxml.jackson.databind.annotation.JsonSerialize;
import com.mijiu.commom.custom.serializable.DesensitizationJsonSerializable;
import com.mijiu.commom.enumerate.DesensitizationStrategyEnum;

import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;

/**
 * @author mijiupro
 */
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.FIELD)
@JacksonAnnotationsInside
@JsonSerialize(using = DesensitizationJsonSerializable.class)
public @interface Desensitization {
    DesensitizationStrategyEnum desensitizationStrategy();//这是自定义的脱敏策略枚举类型,用于指定脱敏策略,获取对应脱敏处理方法

}

2.编写脱敏策略枚举类

脱敏的本质其实就是个字符串的替换,我们在脱敏策略枚举类中通过定义函数接口,维护多种类型脱敏策略对应的字符串替换方法。这样做可以保证可维护性可扩展性。

import lombok.Getter;

import java.util.function.Function;


/**
 * 脱敏策略枚举类,维护对不同类型信息的脱敏处理方式
 * @author mijiupro
 */
@Getter
public enum DesensitizationStrategyEnum {

    // 手机号脱敏策略,保留前三位和后四位
    PHONE(s -> s.replaceAll("(\\d{3})\\d{4}(\\d{4})", "$1****$2")),

    // 邮箱脱敏策略,保留邮箱用户名第一个字符和@符号前后部分
    EMAIL(s -> s.replaceAll("(\\w)[^@]*(@\\w+\\.\\w+)", "$1****$2")),

    // 身份证号脱敏策略,保留前四位和后四位
    ID_CARD(s -> s.replaceAll("(\\d{4})\\d{10}(\\w{4})", "$1*****$2")),

    // 地址脱敏策略,保留省市信息,其余部分脱敏为**
    ADDRESS(s -> s.replaceAll("([\\u4e00-\\u9fa5]{2})[\\u4e00-\\u9fa5]+", "$1**")),

    // 银行卡号脱敏策略,保留前四位和后三位
    BANK_CARD(s -> s.replaceAll("(\\d{4})\\d{8,12}(\\d{3})", "$1************$2")),

    // 姓名脱敏策略,保留姓氏第一个字符,其余部分脱敏为**
    NAME(s -> s.charAt(0) + "**"),

    // 密码脱敏策略,统一显示为******
    PASSWORD(s -> "******");

    private final Function<String, String> desensitization;

    DesensitizationStrategyEnum(Function<String, String> desensitization) {
        this.desensitization = desensitization;
    }

}

3.编写JSON序列化实现

需要清楚

  • 平时接口返回的数据结构直接都是交给默认的序列化器把对象转成json的。
  • 实现脱敏的本质就是在这前面添加了一段逻辑,找到带有脱敏注解的属性然后拿到注解指定的脱敏策略实例化这个脱敏策略枚举类,应用对应的脱敏方法处理需要脱敏字段,得到脱敏后的值交给json生成器得到最终脱敏后的json
import com.fasterxml.jackson.core.JsonGenerator;
import com.fasterxml.jackson.databind.*;

import com.fasterxml.jackson.databind.ser.ContextualSerializer;
import com.mijiu.commom.annotation.Desensitization;
import com.mijiu.commom.enumerate.DesensitizationStrategyEnum;

import java.io.IOException;
import java.util.Objects;

/**
 * 自定义的脱敏JSON序列化器
 * @author mijiupro
 */


public class DesensitizationJsonSerializable extends JsonSerializer<String> implements ContextualSerializer {

    private DesensitizationStrategyEnum desensitizationStrategy; // 脱敏策略

    @Override
    public void serialize(String s, JsonGenerator jsonGenerator, SerializerProvider serializerProvider) throws IOException {
        // 将字符串按照设定的脱敏策略进行脱敏处理后序列化到 JSON 中
        jsonGenerator.writeString(desensitizationStrategy.getDesensitization().apply(s));
    }

    @Override
    public JsonSerializer<?> createContextual(SerializerProvider serializerProvider, BeanProperty beanProperty) throws JsonMappingException {
        // 获取属性上的 Desensitization 注解
        Desensitization annotation = beanProperty.getAnnotation(Desensitization.class);

        // 判断注解不为空且属性类型为 String
        if (Objects.nonNull(annotation) && Objects.equals(String.class, beanProperty.getType().getRawClass())) {
            this.desensitizationStrategy = annotation.desensitizationStrategy(); // 设置脱敏策略
            return this;
        }

        // 返回默认的序列化器
        return serializerProvider.findValueSerializer(beanProperty.getType(), beanProperty);
    }
}

4.编写测试类

/**
 * @author mijiupro
 */
@Data
@Builder
public class PersonalInfo {

    @Desensitization(desensitizationStrategy = DesensitizationStrategyEnum.PHONE)
    private String phone; // 手机号

    @Desensitization(desensitizationStrategy = DesensitizationStrategyEnum.EMAIL)
    private String email; // 邮箱

    @Desensitization(desensitizationStrategy = DesensitizationStrategyEnum.ID_CARD)
    private String idCard; // 身份证号

    @Desensitization(desensitizationStrategy = DesensitizationStrategyEnum.ADDRESS)
    private String address; // 地址

    @Desensitization(desensitizationStrategy = DesensitizationStrategyEnum.BANK_CARD)
    private String bankCard; // 银行卡号

    @Desensitization(desensitizationStrategy = DesensitizationStrategyEnum.NAME)
    private String name; // 姓名

    @Desensitization(desensitizationStrategy = DesensitizationStrategyEnum.PASSWORD)
    private String password; // 密码

}

5.编写测试接口

/**
 * @author mijiupro
 */
@RestController
@RequestMapping("/test/desensitization")
@Tag(name = "脱敏测试接口", description = "脱敏测试接口")
public class DesensitizationTestController {
    @GetMapping("/get-info")
    @Operation(summary = "获取脱敏信息")
    public PersonalInfo getInt() {


        return PersonalInfo.builder()
                .name("言冰云")
                .phone("13812345678")
                .email("mijiu@qq.com")
                .idCard("110101199003073321")
                .address("四川省成都市郫都区百草路一号")
                .password("1234567890")
                .bankCard("62220210001234567890")
                .build();
    }
}

6.接口测试

这里通过swagger3进行接口测试:

Spring Boot3整合knife4j(swagger3)_springboot3 knife4j-CSDN博客文章浏览阅读2.1k次,点赞39次,收藏52次。Knife4j · 集Swagger2及OpenAPI3为一体的增强解决方案. | Knife4j (xiaominfo.com)作者的使用的spring boot 3.2.2为当前最新版,所以依赖导入最新的knife4j 4.4.0。3.1 增强模式 | Knife4j (xiaominfo.com)好一个spring boot项目且版本为3X,项目可正常启动。快速开始 | Knife4j (xiaominfo.com)接下来配置以下接口文档的作者等信息。@Tag注解:标记接口类别。_springboot3 knife4jhttps://blog.csdn.net/qq_62262918/article/details/135761392?spm=1001.2014.3001.5502测试结果:

写在最后

springboot3实现优雅的数据脱敏到这里就结束了,本文共列举了实现了七种常见的类型的数据脱敏。任何问题评论区或私信讨论,欢迎指正。

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

【Python小工具系列】使用 Python 循环批量打开网页链接

&#x1f49d;&#x1f49d;&#x1f49d;欢迎来到我的博客&#xff0c;很高兴能够在这里和您见面&#xff01;希望您在这里可以感受到一份轻松愉快的氛围&#xff0c;不仅可以获得有趣的内容和知识&#xff0c;也可以畅所欲言、分享您的想法和见解。 推荐:kwan 的首页,持续学…

工程项目管理系统专业解决方案!企智汇工程项目管理专业解决方案!

1.企智汇工程项目管理系统打造数智化全流程平台&#xff0c;打通全公司数据&#xff0c;实现公司业财一体化全方位管理。 企智汇工程项目管理系统&#xff0c;打通钉钉与企业微信的入口、可与财务系统做数据对接&#xff0c;统一共享数据源的企业一站式数智化项目管理平台&…

openGauss学习笔记-250 openGauss性能调优-使用Plan Hint进行调优-Join方式的Hint

文章目录 openGauss学习笔记-250 openGauss性能调优-使用Plan Hint进行调优-Join方式的Hint250.1 功能描述250.2 语法格式250.3 参数说明250.4 示例 openGauss学习笔记-250 openGauss性能调优-使用Plan Hint进行调优-Join方式的Hint 250.1 功能描述 指明Join使用的方法&#…

Affinity Publisher:你的出版利器,让创意绽放光彩!mac/win版

Affinity Publisher是一款功能强大的桌面出版软件&#xff0c;专为专业出版人员、设计师和印前专家设计。它提供了从构思到印刷的完整工作流程&#xff0c;让用户能够轻松创建高质量的出版物&#xff0c;包括杂志、书籍、小册子、海报等。 Affinity Publisher软件获取 Affinit…

C语言字节对齐关键字__attribute__((aligned(n)))的使用

0 前言 在进行嵌入式开发的过程中&#xff0c;我们经常会见到对齐操作。这些对齐操作有些是为了便于实现指针操作&#xff0c;有些是为了加速对内存的访问。因此&#xff0c;学习如何使用对齐关键字是对于嵌入式开发是很有必要的。 1 对齐规则 1.0 什么叫做对齐 众所周知&a…

Spring Bean 依赖注入(下)

不管是在属性上面还是在方法上面加了Autowired注解都是根据属性的类型和名字去找bean&#xff0c; set方法多个形参也是这么找 拿到所有的属性和方法的注入点后&#xff0c;会去调用Inject()方法 遍历每一个注入点然后进行注入 字段的注入 一开始肯定是没有缓存的&#xff0…

SpringBoot3+JPA+MySQL实现多数据源的读写分离(基于EntityManagerFactory)

1、简介 在Spring Boot中配置多个数据源并实现自动切换EntityManager&#xff0c;这里我编写了一个RoutingEntityManagerFactory和AOP&#xff08;面向切面编程&#xff09;的方式来实现。 这里我配置了两个数据源&#xff1a;primary和secondary&#xff0c;其中primary主数…

Redis - 高并发场景下的Redis最佳实践_翻过6座大山

文章目录 概述6座大山之_缓存雪崩 &#xff08;缓存全部失效&#xff09;缓存雪崩的两种常见场景如何应对缓存雪崩&#xff1f; 6座大山之_缓存穿透&#xff08;查询不存在的 key&#xff09;缓存穿透的原因解决方案1. 数据校验2. 缓存空值3. 频控4. 使用布隆过滤器 6座大山之_…

hash冲突四种解决办法,hash冲突除了拉链法还有什么?

1. 看hashmap 源码&#xff0c;有个问题&#xff0c;key 存放是 先hash 再与hash值的高16位值 进行异或运算。再与槽位size() 求模取余。如果多个不同的key 得出de数组位置相同。则采用链表依次存储。 2. 那么除了拉链法还有什么其他解决hash冲突的方法呢&#xff1f; a. 建立…

【学习】Web安全测试需要考虑哪些情形

一、数据加密 某些数据需要进行信息加密和过滤后才能在客户端和服务器之间进行传输&#xff0c;包括用户登录密码、信用卡信息等。例如&#xff0c;在登录某银行网站时&#xff0c;该网站必须支持SSL协议&#xff0c;通过浏览器访问该网站时&#xff0c;地址栏的http变成https…

堂哥让我给他做个真人动漫头像

背景 堂哥最喜欢的动漫是死神。他给了我一张死神主角一户的头像&#xff0c;以及自己的头像&#xff0c;希望我产出一张真人动漫头像。 一户的头像&#xff1a; 堂哥自拍照&#xff1a; 最近&#xff0c;有大佬部署了个stable diffusion&#xff0c;正好拿来一试身手。 stab…

vue项目报这个错是 Same `value` exist in the tree: 0008E3000E1A?

警告 "Same value exist in the tree: 0008E3000E1A" 表示在树形选择器中存在相同的值。这通常是由于树形选择器的数据中存在重复的值造成的。就是返回的值中&#xff0c;有俩个id相同

【Redis】数据类型、事务执行、内存淘汰策略

目录 数据类型 Redis事务执行步骤 步骤&#xff1a; redis内存淘汰策略 设置内存淘汰策略 1.设置配置文件 2.通过命令设置 数据类型 官网解释 Understand Redis data types | Redis 首先&#xff0c;Redis 的所有键都是字符串,常用的数据类型有 5 种&#xff1a;Strin…

快速上手 Elasticsearch:Docker Compose 部署详解

最近面试竞争日益激烈&#xff0c;Elasticsearch作为一款广泛应用的中间件&#xff0c;几乎成为面试中必考的知识点。最近&#xff0c;AIGC也备受关注&#xff0c;而好多的AI项目中也采用了Elasticsearch作为向量数据库&#xff0c;因此我们迫切希望学习Elasticsearch。对于学习…

【机器学习】基于变色龙算法优化的BP神经网络分类预测(SSA-BP)

目录 1.原理与思路2.设计与实现3.结果预测4.代码获取 1.原理与思路 【智能算法应用】智能算法优化BP神经网络思路【智能算法】变色龙优化算法&#xff08;CSA)原理及实现 2.设计与实现 数据集&#xff1a; 数据集样本总数2000 多输入多输出&#xff1a;样本特征24&#xff…

工业4.0 底层逻辑

许多场合下&#xff0c;工业4.0 的概念已经被滥用了&#xff0c;它与物联网&#xff0c;工业物联网等概念被滥用一样&#xff0c;几乎什么都往里面装。演变成了一句口号和愿景。许多人并不清楚工业4.0的底层逻辑到底是什么&#xff1f;如何遵循工业4.0 的思想构建新一代智能制造…

社交媒体行业巨头:揭示Facebook的市场地位

引言 随着数字化时代的蓬勃发展&#xff0c;社交媒体已经深刻改变了人们的生活方式和社会交往方式&#xff0c;而Facebook作为其中的领军者&#xff0c;扮演着举足轻重的角色。本文将深入探讨Facebook在社交媒体行业中的市场地位&#xff0c;从用户规模、收入来源、技术创新、…

【Android】美团组件化路由框架WMRouter源码解析

前言 Android无论App开发还是SDK开发&#xff0c;都绕不开组件化&#xff0c;组件化要解决的最大的问题就是组件之间的通信&#xff0c;即路由框架。国内使用最多的两个路由框架一个是阿里的ARouter&#xff0c;另一个是美团的WMRouter。这两个路由框架功能都很强大&#xff0…

智能运维的发展演进

Gartner在2018年提出AIOps&#xff08;Artificial Intelligence for IT Operations&#xff09;&#xff0c;即人工智能在IT运维领域的应用。智能运维在技术方案、平台、场景都更加聚焦&#xff0c;恰逢AI技术飞速发展。用户可以实时监控分析大量的运维数据&#xff0c;预防和防…

python + tensorflow 开局托儿所自动点击脚本

python开局托儿所自动点击脚本 屏幕截图图片数字识别消除算法自动点击 屏幕截图 python 屏幕截图可以使用pyautogui或者PIL。我使用的是PIL中的ImageGrab(要授权)。 image ImageGrab.grab(bbox(0, 0, tool.static_window_width, tool.static_window_height)) image np.arra…