前言

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

一、自定义注解

importcom.fasterxml.jackson.annotation.JacksonAnnotationsInside;importcom.fasterxml.jackson.databind.annotation.JsonSerialize;importjava.lang.annotation.ElementType;importjava.lang.annotation.Retention;importjava.lang.annotation.RetentionPolicy;importjava.lang.annotation.Target;

@Target(ElementType.FIELD)
@Retention(RetentionPolicy.RUNTIME)
@JacksonAnnotationsInside
@JsonSerialize(using
= SensitiveSerializer.class)public @interfaceSensitive {//加密开始位置 int start()default 0;//加密结束位置 int end() default 0;//加密掩码 String mask() default "*";
}

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

importcom.fasterxml.jackson.core.JsonGenerator;importcom.fasterxml.jackson.databind.BeanProperty;importcom.fasterxml.jackson.databind.JsonMappingException;importcom.fasterxml.jackson.databind.JsonSerializer;importcom.fasterxml.jackson.databind.SerializerProvider;importcom.fasterxml.jackson.databind.ser.ContextualSerializer;importorg.springframework.util.StringUtils;importjava.io.IOException;importjava.util.Collections;/***@authorsongwp
* @date 2024-11-15
* @desc 自定义序列化器,用于对敏感字段进行脱敏处理
*/ public class SensitiveSerializer extends JsonSerializer<String> implementsContextualSerializer {privateSensitive sensitive;

@Override
public void serialize(String value, JsonGenerator gen, SerializerProvider serializers) throwsIOException {
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) throwsJsonMappingException {
sensitive
= property.getAnnotation(Sensitive.class);return this;
}
}

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

importcom.fasterxml.jackson.databind.annotation.JsonSerialize;importcom.fasterxml.jackson.databind.ser.std.ToStringSerializer;importcom.songwp.config.Sensitive;importlombok.AllArgsConstructor;importlombok.Data;importlombok.NoArgsConstructor;importjava.io.Serializable;/***@authorsongwp
*
@version1.0
* @date 2024-11-15
* @description: user domain
*/@Data
@AllArgsConstructor
@NoArgsConstructor
public class User implementsSerializable {
@JsonSerialize(using
= ToStringSerializer.class)privateLong id;
@Sensitive(start
= 2, end = 4)privateString name;
@Sensitive(start
= 6, end = 4)privateString idCard;
@Sensitive(start
= 4, end = 3)privateString phone;
}

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

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

标签: none

添加新评论