diff --git a/tool-desensitization/pom.xml b/tool-desensitization/pom.xml new file mode 100644 index 0000000..910786f --- /dev/null +++ b/tool-desensitization/pom.xml @@ -0,0 +1,68 @@ + + + 4.0.0 + + org.springframework.boot + spring-boot-starter-parent + 2.7.10 + + + com.jiaqing + tool-desensitization + 0.0.1-SNAPSHOT + tool-desensitization + 数据脱敏 + + 1.8 + 5.8.5 + + + + org.springframework.boot + spring-boot-starter + + + org.springframework.boot + spring-boot-starter-web + + + cn.hutool + hutool-core + ${hutool.version} + + + org.projectlombok + lombok + true + + + org.springframework.boot + spring-boot-starter-test + test + + + + org.springframework.boot + spring-boot-starter-json + + + + + + + org.springframework.boot + spring-boot-maven-plugin + + + + org.projectlombok + lombok + + + + + + + + diff --git a/tool-desensitization/src/main/java/com/jiaqing/tooldesensitization/ToolDesensitizationApplication.java b/tool-desensitization/src/main/java/com/jiaqing/tooldesensitization/ToolDesensitizationApplication.java new file mode 100644 index 0000000..da76045 --- /dev/null +++ b/tool-desensitization/src/main/java/com/jiaqing/tooldesensitization/ToolDesensitizationApplication.java @@ -0,0 +1,19 @@ +package com.jiaqing.tooldesensitization; + +import org.springframework.boot.SpringApplication; +import org.springframework.boot.autoconfigure.SpringBootApplication; + +/** + * @description: 一个注解解决数据脱敏问题 + * @return: + * @author: woniu + * @time: 2023/4/17 21:11 + */ +@SpringBootApplication +public class ToolDesensitizationApplication { + + public static void main(String[] args) { + SpringApplication.run(ToolDesensitizationApplication.class, args); + } + +} diff --git a/tool-desensitization/src/main/java/com/jiaqing/tooldesensitization/annotation/Desensitization.java b/tool-desensitization/src/main/java/com/jiaqing/tooldesensitization/annotation/Desensitization.java new file mode 100644 index 0000000..3ef572e --- /dev/null +++ b/tool-desensitization/src/main/java/com/jiaqing/tooldesensitization/annotation/Desensitization.java @@ -0,0 +1,38 @@ +package com.jiaqing.tooldesensitization.annotation; + +import com.fasterxml.jackson.annotation.JacksonAnnotationsInside; +import com.fasterxml.jackson.databind.annotation.JsonSerialize; +import com.jiaqing.tooldesensitization.enums.DesensitizationTypeEnum; +import com.jiaqing.tooldesensitization.serialize.DesensitizationSerialize; + +import java.lang.annotation.ElementType; +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; +import java.lang.annotation.Target; + +/** + * 一个注解解决数据脱敏问题! + * @description: 数据脱敏注解 + * @author: woniu + * @time: 2023/4/17 21:35 + */ +@Retention(RetentionPolicy.RUNTIME) +@Target(ElementType.FIELD) +@JacksonAnnotationsInside +@JsonSerialize(using = DesensitizationSerialize.class) +public @interface Desensitization { + /** + * 脱敏数据类型,只要在CUSTOMER的时候,startInclude和endExclude生效 + */ + DesensitizationTypeEnum type() default DesensitizationTypeEnum.CUSTOMER; + + /** + * 开始位置(包含) + */ + int startInclude() default 0; + + /** + * 结束位置(不包含) + */ + int endExclude() default 0; +} diff --git a/tool-desensitization/src/main/java/com/jiaqing/tooldesensitization/api/TestApi.java b/tool-desensitization/src/main/java/com/jiaqing/tooldesensitization/api/TestApi.java new file mode 100644 index 0000000..03bfb3b --- /dev/null +++ b/tool-desensitization/src/main/java/com/jiaqing/tooldesensitization/api/TestApi.java @@ -0,0 +1,36 @@ +package com.jiaqing.tooldesensitization.api; + +import com.jiaqing.tooldesensitization.dto.TestAnnotationDTO; +import com.jiaqing.tooldesensitization.dto.TestDTO; +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RestController; + +/** + * @author: woniu + * @Description 测试api + * @ClassName TestApi + * @Date 2023/4/23 20:16 + **/ +@RestController +@RequestMapping("/test") +public class TestApi { + + @GetMapping + public TestDTO test(){ + TestDTO testDTO = new TestDTO(); + testDTO.setPhone("17677772345"); + return testDTO; + } + + @GetMapping("/test-annotation") + public TestAnnotationDTO testAnnotation(){ + TestAnnotationDTO testAnnotationDTO = new TestAnnotationDTO(); + testAnnotationDTO.setPhone("17677772345"); + testAnnotationDTO.setCustom("111111111111111111"); + testAnnotationDTO.setEmail("1433926101@qq.com"); + testAnnotationDTO.setIdCard("4444199810015555"); + return testAnnotationDTO; + } + +} diff --git a/tool-desensitization/src/main/java/com/jiaqing/tooldesensitization/dto/TestAnnotationDTO.java b/tool-desensitization/src/main/java/com/jiaqing/tooldesensitization/dto/TestAnnotationDTO.java new file mode 100644 index 0000000..5ff5439 --- /dev/null +++ b/tool-desensitization/src/main/java/com/jiaqing/tooldesensitization/dto/TestAnnotationDTO.java @@ -0,0 +1,39 @@ +package com.jiaqing.tooldesensitization.dto; + +import com.jiaqing.tooldesensitization.annotation.Desensitization; +import com.jiaqing.tooldesensitization.enums.DesensitizationTypeEnum; +import lombok.Data; + +import java.io.Serializable; + +/** + * @author: woniu + * @Description 测试DTO + * @ClassName TestDTO + * @Date 2023/4/23 19:43 + **/ +@Data +public class TestAnnotationDTO implements Serializable { + /** + * 自定义 + */ + @Desensitization(type = DesensitizationTypeEnum.CUSTOMER,startInclude = 5,endExclude = 10) + private String custom; + /** + * 手机号 + */ + @Desensitization(type = DesensitizationTypeEnum.MOBILE_PHONE) + private String phone; + /** + * 邮箱 + */ + @Desensitization(type = DesensitizationTypeEnum.EMAIL) + private String email; + /** + * 身份证 + */ + @Desensitization(type = DesensitizationTypeEnum.ID_CARD) + private String idCard; + + +} diff --git a/tool-desensitization/src/main/java/com/jiaqing/tooldesensitization/dto/TestDTO.java b/tool-desensitization/src/main/java/com/jiaqing/tooldesensitization/dto/TestDTO.java new file mode 100644 index 0000000..a3676a2 --- /dev/null +++ b/tool-desensitization/src/main/java/com/jiaqing/tooldesensitization/dto/TestDTO.java @@ -0,0 +1,22 @@ +package com.jiaqing.tooldesensitization.dto; + +import com.fasterxml.jackson.databind.annotation.JsonSerialize; +import com.jiaqing.tooldesensitization.serialize.TestJacksonSerialize; +import lombok.Data; + +import java.io.Serializable; + +/** + * @author: woniu + * @Description 测试DTO + * @ClassName TestDTO + * @Date 2023/4/23 19:43 + **/ +@Data +public class TestDTO implements Serializable { + /** + * 手机号 + */ + @JsonSerialize(using = TestJacksonSerialize.class) + private String phone; +} diff --git a/tool-desensitization/src/main/java/com/jiaqing/tooldesensitization/enums/DesensitizationTypeEnum.java b/tool-desensitization/src/main/java/com/jiaqing/tooldesensitization/enums/DesensitizationTypeEnum.java new file mode 100644 index 0000000..efe7ebc --- /dev/null +++ b/tool-desensitization/src/main/java/com/jiaqing/tooldesensitization/enums/DesensitizationTypeEnum.java @@ -0,0 +1,33 @@ +package com.jiaqing.tooldesensitization.enums; + +/** + * @author: woniu + * @Description 数据脱敏枚举 + * @ClassName DesensitizedTypeEnum + * @Date 2023/4/17 21:39 + **/ +public enum DesensitizationTypeEnum { + //自定义 + CUSTOMER, + //用户id + USER_ID, + //中文名 + CHINESE_NAME, + //身份证号 + ID_CARD, + //座机号 + FIXED_PHONE, + //手机号 + MOBILE_PHONE, + //地址 + ADDRESS, + //电子邮件 + EMAIL, + //密码 + PASSWORD, + //中国大陆车牌,包含普通车辆、新能源车辆 + CAR_LICENSE, + //银行卡 + BANK_CARD +} + diff --git a/tool-desensitization/src/main/java/com/jiaqing/tooldesensitization/serialize/DesensitizationSerialize.java b/tool-desensitization/src/main/java/com/jiaqing/tooldesensitization/serialize/DesensitizationSerialize.java new file mode 100644 index 0000000..374b4eb --- /dev/null +++ b/tool-desensitization/src/main/java/com/jiaqing/tooldesensitization/serialize/DesensitizationSerialize.java @@ -0,0 +1,108 @@ +package com.jiaqing.tooldesensitization.serialize; + +import cn.hutool.core.text.CharSequenceUtil; +import cn.hutool.core.util.DesensitizedUtil; +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 com.jiaqing.tooldesensitization.annotation.Desensitization; +import com.jiaqing.tooldesensitization.enums.DesensitizationTypeEnum; +import lombok.AllArgsConstructor; +import lombok.NoArgsConstructor; + +import java.io.IOException; +import java.util.Objects; + +/** + * @author: woniu + * @Description 脱敏序列化 + * @ClassName DesensitizedSerialize + * @Date 2023/4/17 21:57 + **/ +@NoArgsConstructor +@AllArgsConstructor +public class DesensitizationSerialize extends JsonSerializer implements ContextualSerializer { + private DesensitizationTypeEnum type; + + private Integer startInclude; + + private Integer endExclude; + @Override + public void serialize(String str, JsonGenerator jsonGenerator, SerializerProvider serializerProvider) throws IOException { + switch (type) { + // 自定义类型脱敏 + case CUSTOMER: + jsonGenerator.writeString(CharSequenceUtil.hide(str,startInclude,endExclude)); + break; + // userId脱敏 + case USER_ID: + jsonGenerator.writeString(String.valueOf(DesensitizedUtil.userId())); + break; + // 中文姓名脱敏 + case CHINESE_NAME: + jsonGenerator.writeString(DesensitizedUtil.chineseName(String.valueOf(str))); + break; + // 身份证脱敏 + case ID_CARD: + jsonGenerator.writeString(DesensitizedUtil.idCardNum(String.valueOf(str), 1, 2)); + break; + // 固定电话脱敏 + case FIXED_PHONE: + jsonGenerator.writeString(DesensitizedUtil.fixedPhone(String.valueOf(str))); + break; + // 手机号脱敏 + case MOBILE_PHONE: + jsonGenerator.writeString(DesensitizedUtil.mobilePhone(String.valueOf(str))); + break; + // 地址脱敏 + case ADDRESS: + jsonGenerator.writeString(DesensitizedUtil.address(String.valueOf(str), 8)); + break; + // 邮箱脱敏 + case EMAIL: + jsonGenerator.writeString(DesensitizedUtil.email(String.valueOf(str))); + break; + // 密码脱敏 + case PASSWORD: + jsonGenerator.writeString(DesensitizedUtil.password(String.valueOf(str))); + break; + // 中国车牌脱敏 + case CAR_LICENSE: + jsonGenerator.writeString(DesensitizedUtil.carLicense(String.valueOf(str))); + break; + // 银行卡脱敏 + case BANK_CARD: + jsonGenerator.writeString(DesensitizedUtil.bankCard(String.valueOf(str))); + break; + default: + } + + } + + @Override + public JsonSerializer createContextual(SerializerProvider serializerProvider, BeanProperty beanProperty) throws JsonMappingException { + if (beanProperty != null) { + // 判断数据类型是否为String类型 + if (Objects.equals(beanProperty.getType().getRawClass(), String.class)) { + // 获取定义的注解 + Desensitization desensitization = beanProperty.getAnnotation(Desensitization.class); + // 为null + if (desensitization == null) { + desensitization = beanProperty.getContextAnnotation(Desensitization.class); + } + // 不为null + if (desensitization != null) { + // 创建定义的序列化类的实例并且返回,入参为注解定义的type,开始位置,结束位置。 + return new DesensitizationSerialize(desensitization.type(), desensitization.startInclude(), + desensitization.endExclude()); + } + } + + return serializerProvider.findValueSerializer(beanProperty.getType(), beanProperty); + } + return serializerProvider.findNullValueSerializer(null); + } +} diff --git a/tool-desensitization/src/main/java/com/jiaqing/tooldesensitization/serialize/TestJacksonSerialize.java b/tool-desensitization/src/main/java/com/jiaqing/tooldesensitization/serialize/TestJacksonSerialize.java new file mode 100644 index 0000000..d3c1721 --- /dev/null +++ b/tool-desensitization/src/main/java/com/jiaqing/tooldesensitization/serialize/TestJacksonSerialize.java @@ -0,0 +1,23 @@ +package com.jiaqing.tooldesensitization.serialize; + +import cn.hutool.core.util.DesensitizedUtil; +import com.fasterxml.jackson.core.JsonGenerator; +import com.fasterxml.jackson.databind.JsonSerializer; +import com.fasterxml.jackson.databind.SerializerProvider; +import lombok.SneakyThrows; + +/** + * @author: woniu + * @Description 脱敏序列化 + * @ClassName DesensitizedSerialize + * @Date 2023/4/17 21:57 + **/ +public class TestJacksonSerialize extends JsonSerializer { + + @Override + @SneakyThrows + public void serialize(String str, JsonGenerator jsonGenerator, SerializerProvider serializerProvider) { + // 使用我们的hutool工具类进行手机号脱敏 + jsonGenerator.writeString(DesensitizedUtil.fixedPhone(String.valueOf(str))); + } +} diff --git a/tool-desensitization/src/main/resources/application.properties b/tool-desensitization/src/main/resources/application.properties new file mode 100644 index 0000000..8b13789 --- /dev/null +++ b/tool-desensitization/src/main/resources/application.properties @@ -0,0 +1 @@ + diff --git a/tool-desensitization/src/test/java/com/jiaqing/tooldesensitization/ToolDesensitizationApplicationTests.java b/tool-desensitization/src/test/java/com/jiaqing/tooldesensitization/ToolDesensitizationApplicationTests.java new file mode 100644 index 0000000..b8b6005 --- /dev/null +++ b/tool-desensitization/src/test/java/com/jiaqing/tooldesensitization/ToolDesensitizationApplicationTests.java @@ -0,0 +1,16 @@ +package com.jiaqing.tooldesensitization; + +import cn.hutool.core.util.DesensitizedUtil; +import org.junit.jupiter.api.Test; +import org.springframework.boot.test.context.SpringBootTest; + +@SpringBootTest +class ToolDesensitizationApplicationTests { + + @Test + void contextLoads() { + String phoneNumber = "17677772345"; + System.out.println(DesensitizedUtil.mobilePhone(phoneNumber)); + } + +} diff --git a/tool-desensitization/tool-desensitization.iml b/tool-desensitization/tool-desensitization.iml new file mode 100644 index 0000000..2addc8b --- /dev/null +++ b/tool-desensitization/tool-desensitization.iml @@ -0,0 +1,91 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file