在返回字段时有时需要对电话,地址等字段进行脱敏处理
1. 定义枚举脱敏类
使用函数编程,绑定函数操作
public enum DataMaskEnum { /** * 名称脱敏 */ USERNAME(s->s.replaceAll("(\\S)\\S(\\S*)","$1*$2")), /** * 手机号脱敏 */ PHONE(s->s.replaceAll("(\\d{3})\\d{4}(\\d{4})","$1****$2")), /** * 地址脱敏 */ ADDRESS(s->s.replaceAll("(\\S{3})\\S{2}(\\S*)\\S{2}","$1****$2****")) ; private Function<String,String> function; DataMaskEnum(Function<String, String> function) { this.function = function; } public Function<String,String> function(){ return this.function; } }
2. 定义脱敏注解
@Target({ElementType.FIELD,ElementType.TYPE}) @Retention(RetentionPolicy.RUNTIME) @Documented @JacksonAnnotationsInside @JsonSerialize(using = DataMaskingSerializer.class) public @interface DataMask { DataMaskEnum function() default DataMaskEnum.ADDRESS; }
3. 结合jackson脱敏处理
public final class DataMaskingSerializer extends JsonSerializer<String> implements ContextualSerializer { private DataMaskEnum dataMaskEnum; @Override public void serialize(String s, JsonGenerator jsonGenerator, SerializerProvider serializerProvider) throws IOException { jsonGenerator.writeString(dataMaskEnum.function().apply(s)); } @Override public JsonSerializer<?> createContextual(SerializerProvider serializerProvider, BeanProperty beanProperty) throws JsonMappingException { DataMask annotation = beanProperty.getAnnotation(DataMask.class); if (annotation != null && String.class.equals(beanProperty.getType().getRawClass())){ dataMaskEnum = annotation.function(); return this; } return serializerProvider.findValueSerializer(beanProperty.getType(),beanProperty); } }
4. 在实体类上添加注解,请求接口
@Data public class PrjAssignDetailVO { @Schema(description ="客户联系电话") @DataMask(function = DataMaskEnum.PHONE) private String contactPhone; }
@GetMapping("/test/{id}") public R test(@PathVariable("id") String id){ PrjAssign one = prjAssignService.lambdaQuery().eq(PrjAssign::getId, id).one(); PrjAssignDetailVO prjAssignDetailVO = new PrjAssignDetailVO(); BeanUtil.copyProperties(one, prjAssignDetailVO); return R.ok(prjAssignDetailVO); }