- 背景
通常接口返回值中的一些敏感数据也是要脱敏的,比如身份证号、手机号码…通常的手段就是用*隐藏一部分数据,当然也可以根据自己需求定制 - 方案 参考原文
下面例子,利用Jackson在序列化阶段对特定字段进行脱敏 - 代码
import com.fasterxml.jackson.annotation.JacksonAnnotationsInside;
import com.fasterxml.jackson.databind.annotation.JsonSerialize;
import demo.func.SensitiveJsonSerializer;
import demo.func.SensitiveStrategy;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.FIELD)
@JacksonAnnotationsInside
@JsonSerialize(using = SensitiveJsonSerializer.class)
public @interface Sensitive {
SensitiveStrategy strategy();
}
import java.util.function.Function;
public enum SensitiveStrategy {
PHONE(s -> s.replaceAll("(\\d{3})\\d{4}(\\d{4})", "$1****$2"));
private final Function<String, String> desensitizer;
SensitiveStrategy(Function<String, String> desensitizer) {
this.desensitizer = desensitizer;
}
public Function<String, String> desensitizer() {
return desensitizer;
}
}
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 demo.annotation.Sensitive;
import java.io.IOException;
import java.util.Objects;
public class SensitiveJsonSerializer extends JsonSerializer<String> implements ContextualSerializer {
private SensitiveStrategy strategy;
@Override
public JsonSerializer<?> createContextual(SerializerProvider provider, BeanProperty property) throws JsonMappingException {
Sensitive annotation = property.getAnnotation(Sensitive.class);
if (Objects.nonNull(annotation) && Objects.equals(String.class, property.getType().getRawClass())) {
this.strategy = annotation.strategy();
return this;
}
return provider.findValueSerializer(property.getType(), property);
}
@Override
public void serialize(String value, JsonGenerator gen, SerializerProvider serializerProvider) throws IOException {
gen.writeString(strategy.desensitizer().apply(value));
}
}
@Data
@AllArgsConstructor
public class SecretStr {
@Sensitive(strategy = SensitiveStrategy.PHONE)
private String phone;
private String name;
}
@RestController
public class TestController {
@GetMapping("/getSecret")
public R<SecretStr> getSecret(){
SecretStr secretStr = new SecretStr("15068433245","zs");
return R.success(secretStr);
}
}
- 结果
{
"code": 200,
"msg": "操作成功",
"data": {
"phone": "150****3245",
"name": "zs"
}
}