在返回欄位時有時需要對電話,地址等欄位進行脫敏處理
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); }