Java自定义注解实现数据脱敏

 更新时间:2023年07月21日 11:38:05   作者:Xiao5xiao122  
在实际开发中经常会遇到有一些信息不能全部展示用户,需要隐藏(可以叫脱敏),所以本文为大家分享了利用自定义注解实现数据脱敏的示例代码,需要的可以参考下

自定义注解实现数据脱敏,,国密加解密(sm4)

在实际开发中经常会遇到有一些信息不能全部展示用户,需要隐藏(可以叫脱敏)一部分的情况比如地址,电话,手机号,身份证等。脱敏的做法目前我知道的方法有:

1):业务代码脱敏:顾名思义就是拿到数据需要脱敏的那个字段进过一系列的脱敏规则替换成自己想要的格式。

2):自定义注解+aop切面的方式去完成字段脱敏的目的。

3):自定义注解+序列化的方式对数据进行脱敏。

其中效率最慢的当属于代码业务代码方式,最优的方式当属于自定义注解的方式,减少代码量,提高工作效率,需要脱敏的字段仅需要加一个注解就可以达到目的。

今天就记录下第三种方式,自定义注解+序列化的方式。

首先先定义一个需要脱敏的策略

/**
 * @description: 脱敏策略
 * @author: 
 * @date: 2023/6/18 19:45
 * @Version: 1.0
 */
public enum DesensitizationEnum {
    /**
     * 名称脱敏
     */
    USERNAME(s -> s.replaceAll("(\\S)\\S(\\S*)", "$1*$2"))
    ,
    /**
     * 手机号脱敏
     */
    MOBILE_PHONE(s -> s.replaceAll("(\\d{3})\\d{4}(\\d{4})", "$1****$2"))
    ,
    /**
     *地址脱敏
     */
    ADDRESS(s -> s.replaceAll("(\\S{3})\\S{2}(\\S*)\\S{2}", "$1****$2****"))
    ;
    /**
     * 成员变量  是一个接口类型
     */
    private Function<String, String> function;
    DesensitizationEnum(Function<String, String> function) {
        this.function = function;
    }
    public Function<String, String> function() {
        return this.function;
    }
}

然后自定义一个注解

import com.chaozhou.test01.dingShiRenWu.Annontion.Aspect.DesensitizationEnum;
import com.fasterxml.jackson.annotation.JacksonAnnotationsInside;
import com.fasterxml.jackson.databind.annotation.JsonSerialize;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
/**
 * @description:
 * @author:
 * @date: 2023/6/18 17:23
 * @Version: 1.0
 */
@Target({ElementType.FIELD}) //表明作用在字段上
@Retention(RetentionPolicy.RUNTIME) //什么情况下生效
@JacksonAnnotationsInside //标明序列化
@JsonSerialize(using = DesensitizationDataSerialize.class)
public @interface DesensitizationData {
    DesensitizationEnum function();
}

然后自定义一个序列化器

import com.fasterxml.jackson.core.JsonGenerator;
import com.fasterxml.jackson.databind.BeanProperty;
import com.fasterxml.jackson.databind.JsonMappingException;
import com.fasterxml.jackson.databind.JsonSerializer;
import com.fasterxml.jackson.databind.SerializerProvider;
import com.fasterxml.jackson.databind.ser.ContextualSerializer;
import lombok.NoArgsConstructor;
import java.io.IOException;
import java.util.Objects;
/**
 * @description: 数据脱敏序列化器
 * @author: 
 * @date: 2023/6/18 19:17
 * @Version: 1.0
 */
@NoArgsConstructor
public class DesensitizationDataSerialize extends JsonSerializer<String> implements ContextualSerializer {
    private DesensitizationEnum fuincation;
    @Override
    public JsonSerializer<?> createContextual(SerializerProvider serializerProvider, BeanProperty beanProperty) throws JsonMappingException {
        DesensitizationData annotation = beanProperty.getAnnotation(DesensitizationData.class);
        if(Objects.nonNull(annotation) && Objects.equals(beanProperty.getType().getRawClass(),String.class)){
            this.fuincation = annotation.function();
            return this;
        }
        return serializerProvider.findValueSerializer(beanProperty.getType(),beanProperty);
    }
    @Override
    public void serialize(String s, JsonGenerator jsonGenerator, SerializerProvider serializerProvider) throws IOException {
        jsonGenerator.writeString(fuincation.function().apply(s));
    }
}

这样一个自定义脱敏注解就完成了。

使用方法:

只需要在返回参数需要脱敏的字段上加上响应注解就可以了

public class User implements Serializable {
    @TableId("id")
    private Integer id;
    @JsonFormat(pattern = "yyyy-MM-dd",timezone = "GMT+8")
    @ApiModelProperty(value = "出生年月")
    private Date birthday;
    @ApiModelProperty(value = "性别")
    private String gender;
    @ApiModelProperty(value = "姓名")
    private String username;
    @ApiModelProperty(value = "密码")
    private String password;
    @ApiModelProperty(value = "备注")
    private String remark;
    @ApiModelProperty(value = "状态")
    private String station;
    @ApiModelProperty(value = "联系电话")
    //手机号脱敏
    @DesensitizationData(function = DesensitizationEnum.MOBILE_PHONE)
    private String telephone;
}

结果

手机号已经脱敏成功,该方法单条,多条数据都支持。

国密加解密

需要用到的依赖,可以直接用hutool整合的框架实现

<dependency>
            <groupId>cn.hutool</groupId>
            <artifactId>hutool-all</artifactId>
            <version>5.7.16</version>
        </dependency>
        <!--以下依赖不加亲测也可以实现-->
        <dependency>
            <groupId>org.bouncycastle</groupId>
            <artifactId>bcprov-jdk15on</artifactId>
            <version>1.60</version>
        </dependency>

在以上方法中的策略中加入加解密规则

然后在需要加密或解密的字段中加入该注解,并注解标注正确的策略方式

修改一下上面的序列化器,防止需要需要解密的字段值我空的时候报“Null input buffer”的错

列表字段加密前

列表加密后

工具准备的好,代码效率高了不少。

到此这篇关于Java自定义注解实现数据脱敏的文章就介绍到这了,更多相关Java数据脱敏内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!

相关文章

  • Javaweb请求转发及重定向实现详解

    Javaweb请求转发及重定向实现详解

    这篇文章主要介绍了Javaweb请求转发及重定向实现详解,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以参考下
    2020-07-07
  • Java KindEditor粘贴图片自动上传到服务器功能实现

    Java KindEditor粘贴图片自动上传到服务器功能实现

    这篇文章主要介绍了Java KindEditor粘贴图片自动上传到服务器功能实现,本文给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友可以参考下
    2023-04-04
  • SpringBoot自定义bean绑定实现

    SpringBoot自定义bean绑定实现

    这篇文章主要介绍了SpringBoot自定义bean绑定,最常见的配置绑定的场景,是在自定义的bean中通过@Value注解将某个属性和对应的配置绑定
    2022-10-10
  • 详解Java并发编程之原子类

    详解Java并发编程之原子类

    这篇文章主要为大家介绍了Java并发编程之原子类介绍,有需要的朋友可以借鉴参考下,希望能够有所帮助,祝大家多多进步,早日升职加薪
    2023-04-04
  • 浅谈Spring refresh的工作流程

    浅谈Spring refresh的工作流程

    这篇文章主要介绍了浅谈Spring refresh的工作流程,refresh 是 AbstractApplicationContext 中的一个方法,负责初始化 ApplicationContext容器,让我们一起来学习一下吧
    2023-04-04
  • Java编程Commons lang组件简介

    Java编程Commons lang组件简介

    这篇文章主要介绍了Java编程Commons lang组件的相关内容,十分具有参考意义,需要的朋友可以了解下。
    2017-09-09
  • application作用域实现用户登录挤掉之前登录用户代码

    application作用域实现用户登录挤掉之前登录用户代码

    这篇文章主要介绍了application作用域实现用户登录挤掉之前登录用户代码,具有一定参考价值,需要的朋友可以了解下。
    2017-11-11
  • 解决java try throw exception finally遇上return break continue造成异常丢失

    解决java try throw exception finally遇上return break conti

    这篇文章主要介绍了解决java try throw exception finally遇上return break continue造成异常丢失问题,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教
    2023-11-11
  • SpringBoot+WebSocket向前端推送消息的实现示例

    SpringBoot+WebSocket向前端推送消息的实现示例

    WebSocket是一种在单个TCP连接上进行全双工通信的协议,允许服务器主动向客户端推送信息,同时也能从客户端接收信息,本文主要介绍了SpringBoot+WebSocket向前端推送消息的实现示例,感兴趣的可以了解一下
    2024-08-08
  • Java 实现链表结点插入

    Java 实现链表结点插入

    这篇文章主要介绍了Java 实现链表结点插入操作,具有很好的参考价值,希望对大家有所帮助。一起跟随小编过来看看吧
    2021-02-02

最新评论