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

news2024/11/16 13:26:34

 

⛰️个人主页:     蒾酒

🔥系列专栏:《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实现优雅的数据脱敏到这里就结束了,本文共列举了实现了七种常见的类型的数据脱敏。任何问题评论区或私信讨论,欢迎指正。

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

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

相关文章

数据在内存里的存储(1)【整数在内存中的存储】【什么是大小端】

一.整数在内存里的存储 我们都知道&#xff0c;关于整数的二进制表示方法有三种&#xff0c;原码&#xff0c;反码和补码。而正数的原码&#xff0c;反码&#xff0c;补码都相等。而负数的表示方法各不相同。原码&#xff1a;直接将数值按照正负数的形式翻译成二进制得到的就是…

【Unity】uDD插件抓屏文字显示不清晰怎么办?

【背景】 之前介绍过用一款简称uDD&#xff08;uDesktopDuplication&#xff09;的开源插件抓取电脑桌面。整体效果不错&#xff0c;看电影很流畅。但是当切换到文档&#xff0c;或者仔细看任何UI的文字部分时&#xff0c;发现就模糊了。 【分析】 由于是依托于Canvas上的Te…

备考的秘密武器:一招清除笔迹,试卷、表格再利用!

擦除试卷笔迹的功能可以用于多种场合&#xff0c;尤其适用于教育领域和文档管理工作。以下是一些具体的应用场景&#xff1a; 教学复习&#xff1a;教师可以使用这个功能来清除已批改的试卷上的笔迹&#xff0c;以便重复使用试卷进行讲解或作为模板设计新的题目。 资料归档&a…

Linux中ifconfig无法查看ip解决

安装net-tool插件 sudo yum install net-tools

VUE中添加视频播放功能

转载https://www.cnblogs.com/gg-qq/p/10782848.html 常见错误 vue-video-player下载后‘vue-video-player/src/custom-theme.css‘找不到 解决方法 卸载原来的video-play版本 降低原来的版本 方法一 npm install vue-video-player5.0.1 --save 方法二 或者是在pack.json中直…

力扣刷题Days25-45. 跳跃游戏 II(js)

目录 1&#xff0c;题目 2&#xff0c;代码 贪心算法正向查找 3&#xff0c;学习 解题思路 具体代码处理 数组遍历的最后边界的处理&#xff1a; 1&#xff0c;题目 给定一个长度为 n 的 0 索引整数数组 nums。初始位置为 nums[0]。 每个元素 nums[i] 表示从索引 i 向…

华为ensp中vrrp虚拟路由器冗余协议 原理及配置命令

CSDN 成就一亿技术人&#xff01; 作者主页&#xff1a;点击&#xff01; ENSP专栏&#xff1a;点击&#xff01; CSDN 成就一亿技术人&#xff01; ————前言————— VRRP&#xff08;Virtual Router Redundancy Protocol&#xff0c;虚拟路由器冗余协议&#xff0…

八大排序算法之希尔排序

希尔排序是插入排序的进阶版本&#xff0c;他多次调用插入排序&#xff0c;在插入排序上进行了改造&#xff0c;使其处理无序的数据时候更快 核心思想&#xff1a;1.分组 2.直接插入排序&#xff1a;越有序越快 算法思想&#xff1a; 间隔式分组&#xff0c;利用直接插入排序…

HTML 常用标签总结

本篇文章总结了一些我在学习html时所记录的标签&#xff0c;虽然总结并不是非常全面&#xff0c;但都是一些比较常用的。 html元素标签 首先一个html界面是由无数个元素标签组成的&#xff0c;每个元素具有它的属性 1.input 单行文本框 标签type属性——text <input ty…

【windows】安装 Tomcat 及配置环境变量

&#x1f468;‍&#x1f393;博主简介 &#x1f3c5;云计算领域优质创作者   &#x1f3c5;华为云开发者社区专家博主   &#x1f3c5;阿里云开发者社区专家博主 &#x1f48a;交流社区&#xff1a;运维交流社区 欢迎大家的加入&#xff01; &#x1f40b; 希望大家多多支…

视频号小店如何开店,个人可以做吗?完整版开店教程分享

大家好&#xff0c;我是电商花花。 视频号小店现在成了新的电商创业新渠道&#xff0c;这两年视频号也迎来了大爆发&#xff0c;很多朋友也都靠着视频号、视频号小店赚到了人生第一桶金&#xff0c;让很多没有接触过视频号的朋友直流口水。 那视频号小店赚钱吗&#xff1f;个人…

OpenLayers基础教程——WebGLPoints图层样式的设置方法

1、前言 前一篇博客介绍了如何在OpenLayers中使用WebGLPoints加载海量数据点的方法&#xff0c;这篇博客就来介绍一下WebGLPoints图层的样式设置问题。 2、样式运算符 在VectorLayer图层中&#xff0c;我们只需要创建一个ol.style.Style对象即可&#xff0c;WebGLPoints则不…

研华工控机610L学习笔记2:visualstudio与第一个C#程序

今日继续学习工控机 C# 编程相关知识&#xff1a; 这篇结束后我将先进行一段时间的C#的学习研究&#xff0c;并写一些C#的笔记 后续再更新工控机编程设计相关 目录 1、安装visualstudio&#xff1a; 2、创建第一个C#程序&#xff1a; 3、寻找C#解决方案源文件&#xff1a; …

《深入浅出LLM 》(二):大模型基础知识

&#x1f389;AI学习星球推荐&#xff1a; GoAI的学习社区 知识星球是一个致力于提供《机器学习 | 深度学习 | CV | NLP | 大模型 | 多模态 | AIGC 》各个最新AI方向综述、论文等成体系的学习资料&#xff0c;配有全面而有深度的专栏内容&#xff0c;包括不限于 前沿论文解读、…

DM-达梦数据库实时主备搭建

dm实时主备说明 将主库产生的 Redo日志传输到备库&#xff0c;备库接收并重演Redo日志&#xff0c;从而实现备库与主库的数据同步。 一、环境准备 1.1、配置环境准备 首先搭建实时主备&#xff0c;要规划好机器的&#xff0c;我准备两台机器服务器 主服务器 mast…

小目标检测篇 | YOLOv8改进之增加小目标检测层(针对Neck网络为AFPN)

前言:Hello大家好,我是小哥谈。小目标检测是计算机视觉领域中的一个研究方向,旨在从图像或视频中准确地检测和定位尺寸较小的目标物体。相比于常规目标检测任务,小目标检测更具挑战性,因为小目标通常具有低分辨率、低对比度和模糊等特点,容易被背景干扰或遮挡。本篇文章就…

【C语言】tcp_sendmsg_locked

一、讲解 tcp_sendmsg_locked 函数是 Linux 内核中实现 TCP 数据发送的一个核心函数。这个函数被调用来将用户空间的数据通过 TCP 发送出去。以下是该函数的基本工作流程的中文解释&#xff1a; 1. 函数初始化和检查&#xff1a; - 它首先检查是否使用了 TCP 零拷贝发送&am…

【webpack】----错误解决【Cannot read properties of undefined (reading ‘tap‘)】

1. 报错场景 安装 webpack-obfuscator 后&#xff0c;进行 js 代码混淆编译的时候报错。 2. 报错截图 3. 错误原因 通常是由于版本不兼容或配置错误引起的。 4. 查询本地 webpack 版本 4.1 查询命令 npm 查询 npm view webpack versionyarn 查询 yarn info webpack ver…

Java学习笔记 | Java基础语法 | 03 | 流程控制语句

文章目录 0 前言1.流程控制语句1.1 流程控制语句分类1.2 顺序结构 2.判断语句2.1 if语句1. if语句格式1练习1&#xff1a;老丈人选女婿练习2&#xff1a;考试奖励 2. if语句格式2练习1&#xff1a;吃饭练习2&#xff1a;影院选座 3. if语句格式3练习1&#xff1a;考试奖励 2.2 …

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

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