首先定义脱敏类型枚举类

public enum SensitiveType {
    /**
     * 中文名
     */
    CHINESE_NAME,
    /**
     * 手机号
     */
    MOBILE_PHONE;
}

定义脱敏注解

@Retention(RetentionPolicy.RUNTIME)
@JacksonAnnotationsInside
@JsonSerialize(using = SensitiveInfoSerialize.class)
public @interface SensitiveInfo {
  public SensitiveType value();
}

脱敏序列化类

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 java.io.IOException;
import java.util.Objects;

public class SensitiveInfoSerialize extends JsonSerializer<String> implements ContextualSerializer {

    private SensitiveType type;

    public SensitiveInfoSerialize() {
    }

    public SensitiveInfoSerialize(final SensitiveType type) {
        this.type = type;
    }

    @Override
    public void serialize(String value, JsonGenerator gen, SerializerProvider serializers) throws IOException {
        switch (this.type) {
            case CHINESE_NAME: {
                gen.writeString(SensitiveInfoUtils.chineseName(value));
                break;
            }
            case MOBILE_PHONE: {
                gen.writeString(SensitiveInfoUtils.mobilePhone(value));
                break;
            }
        }
    }



    @Override
    public JsonSerializer<?> createContextual(SerializerProvider serializerProvider, BeanProperty property) throws JsonMappingException {
        // 为空直接跳过
        if (property != null) {
            // 非 String 类直接跳过
            if (Objects.equals(property.getType().getRawClass(), String.class)) {
                SensitiveInfo sensitiveInfo = property.getAnnotation(SensitiveInfo.class);
                if (sensitiveInfo == null) {
                    sensitiveInfo = property.getContextAnnotation(SensitiveInfo.class);
                }

                // 如果能得到注解,就将注解的 value 传入 SensitiveInfoSerialize
                if (sensitiveInfo != null) {

                    return new SensitiveInfoSerialize(sensitiveInfo.value());
                }
            }
            return serializerProvider.findValueSerializer(property.getType(), property);
        }
        return serializerProvider.findNullValueSerializer(property);
    }
}

脱敏工具类

public class SensitiveInfoUtils {

    public static String chineseName(final String fullName) {
        if (StringUtils.isBlank(fullName)) {
            return "";
        }

        final String name = StringUtils.left(fullName, 1);
        return StringUtils.rightPad(name, StringUtils.length(fullName), "*");
    }

    public static String mobilePhone(final String phone) {
        if (StringUtils.isBlank(phone)) {
            return "";
        }
        return phone.replaceAll("(\\d{3})\\d{4}(\\d{4})", "$1****$2");
    }

}

需要脱敏的实体类

@Setter
@Getter
@NoArgsConstructor
@AllArgsConstructor
public class User {

    private Integer id;

    @SensitiveInfo(SensitiveType.CHINESE_NAME)
    private String username;

    @SensitiveInfo(SensitiveType.MOBILE_PHONE)
    private String phone;

    private String password;
}

需要脱敏的实体字段,需要脱敏的字段需要添加@SensitiveInfo注解,并指定脱敏类型