自定义注解进行数据脱敏

前言

有些时候,我们可能对输出的某些字段要做特殊的处理在输出到前端,比如:身份证号,电话等信息,在前端展示的时候我们需要进行脱敏处理,这时候通过自定义注解就非常的有用了。在Jackson中要自定义注解,我们可以通过**@JacksonAnnotationsInside**注解来实现,如下示例:

一、自定义注解

复制代码
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;

@Target(ElementType.FIELD)
@Retention(RetentionPolicy.RUNTIME)
@JacksonAnnotationsInside
@JsonSerialize(using = SensitiveSerializer.class)
public @interface Sensitive {

    //加密开始位置
    int start()default 0 ;

    //加密结束位置
    int end() default 0 ;

    //加密掩码
    String mask() default "*" ;
}

二、自定义序列化处理器SensitiveSerializer

复制代码
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 org.springframework.util.StringUtils;
import java.io.IOException;
import java.util.Collections;

/**
 * @author songwp
 * @date 2024-11-15
 * @desc 自定义序列化器,用于对敏感字段进行脱敏处理
 */
public class SensitiveSerializer extends JsonSerializer<String> implements ContextualSerializer {

    private Sensitive sensitive;

    @Override
    public void serialize(String value, JsonGenerator gen, SerializerProvider serializers) throws IOException {
        String val = value;
        if (sensitive != null && StringUtils.hasLength(val)) {
            String m = sensitive.mask();
            int start = sensitive.start();
            int end = sensitive.end();
            int totalLength = value.length();
            if (totalLength <= 2) {
                val = totalLength == 1 ? value + m : value.substring(0, 1) + m;
            } else if (totalLength <= 6) {
                val = value.substring(0, 1) + String.join("", Collections.nCopies(totalLength - 2, m)) + value.substring(totalLength - 1);
            } else {
                int prefixLength = Math.min(start, totalLength - 1);
                int suffixLength = Math.min(end, totalLength - 1);
                if (prefixLength > totalLength) {
                    prefixLength = totalLength / 2;
                }
                if (suffixLength > totalLength) {
                    suffixLength = totalLength / 2;
                }
                int maskLength = Math.max(0, totalLength - (prefixLength + suffixLength));
                if (maskLength == 0) {
                    prefixLength -= 2;
                    suffixLength -= 2;
                    maskLength = Math.max(2, totalLength - (prefixLength + suffixLength));
                }
                prefixLength = Math.min(prefixLength, totalLength - 1);
                suffixLength = Math.min(suffixLength, totalLength - 1);
                maskLength = totalLength - prefixLength - suffixLength;
                val = value.substring(0, prefixLength) + String.join("", Collections.nCopies(maskLength, m)) + value.substring(totalLength - suffixLength);
            }
        }
        gen.writeString(val);
    }

    @Override
    public JsonSerializer<?> createContextual(SerializerProvider prov, BeanProperty property) throws JsonMappingException {
        sensitive = property.getAnnotation(Sensitive.class);
        return this;
    }
}

三、在输出的Java Bean中使用上面的注解

复制代码
import com.fasterxml.jackson.databind.annotation.JsonSerialize;
import com.fasterxml.jackson.databind.ser.std.ToStringSerializer;
import com.songwp.config.Sensitive;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
import java.io.Serializable;

/**
 * @author songwp
 * @version 1.0
 * @date 2024-11-15
 * @description: user domain
 */
@Data
@AllArgsConstructor
@NoArgsConstructor
public class User implements Serializable {
    @JsonSerialize(using = ToStringSerializer.class)
    private Long id;
    @Sensitive(start = 2, end = 4)
    private String name;
    @Sensitive(start = 6, end = 4)
    private String idCard;
    @Sensitive(start = 4, end = 3)
    private String phone;
}

四、在前端展示结果如下:

敏感数据得到了脱敏处理。

相关推荐
皮卡蛋炒饭.1 分钟前
C++中既重要又困难的部分—类和对象
java·开发语言
kyle~4 分钟前
C++---初始化列表(initializer_list)
java·c++·list
命苦的孩子6 分钟前
Java 数学工具类 Math
java·开发语言
练习时长两年半的程序员小胡15 分钟前
JVM 垃圾回收机制全景解析:从对象回收到收集算法
java·jvm·算法·垃圾回收
笑衬人心。19 分钟前
JVM 笔记:类加载、内存管理、垃圾收集与垃圾收集器
java·jvm·笔记
程序猿小D22 分钟前
Java项目:基于SSM框架实现的进销存管理系统【ssm+B/S架构+源码+数据库+毕业论文+远程部署】
java·数据库·mysql·ssm·jsp·毕业论文·进销存管理系统
得物技术28 分钟前
Java volatile 关键字到底是什么|得物技术
java·后端
HoHeHa30 分钟前
IDEA 手动下载安装数据库驱动,IDEA无法下载数据库驱动问题解决方案,IDEA无法连接数据库解决方案(通用,Oracle为例)
java·数据库·intellij-idea
你可以叫我仔哥呀35 分钟前
Java程序员学从0学AI(七)
java·开发语言·人工智能·ai·spring ai
杨DaB1 小时前
【SpringMVC】MVC中Controller的配置 、RestFul的使用、页面重定向和转发
java·笔记·后端·学习·spring·mvc·restful