自定义注解进行数据脱敏

前言

有些时候,我们可能对输出的某些字段要做特殊的处理在输出到前端,比如:身份证号,电话等信息,在前端展示的时候我们需要进行脱敏处理,这时候通过自定义注解就非常的有用了。在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; }

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

自定义注解进行数据脱敏

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

发表评论

评论已关闭。

相关文章