mirror of
				https://gitee.com/hhyykk/ipms-sjy.git
				synced 2025-11-01 02:38:43 +08:00 
			
		
		
		
	feat: 支持 vo 返回的脱敏
This commit is contained in:
		| @@ -1,21 +0,0 @@ | ||||
| package cn.iocoder.yudao.framework.desensitize.annotation.constraints; | ||||
|  | ||||
| import cn.iocoder.yudao.framework.desensitize.annotation.SliderDesensitize; | ||||
| import com.fasterxml.jackson.annotation.JacksonAnnotationsInside; | ||||
|  | ||||
| import java.lang.annotation.Documented; | ||||
| import java.lang.annotation.ElementType; | ||||
| import java.lang.annotation.Retention; | ||||
| import java.lang.annotation.RetentionPolicy; | ||||
| import java.lang.annotation.Target; | ||||
|  | ||||
| /** | ||||
|  * 银行卡号 | ||||
|  */ | ||||
| @Documented | ||||
| @Target({ElementType.FIELD}) | ||||
| @Retention(RetentionPolicy.RUNTIME) | ||||
| @JacksonAnnotationsInside | ||||
| @SliderDesensitize(prefixKeep = 6, suffixKeep = 2, replacer = "*") // 银行卡号;比如:9988002866797031脱敏之后为998800********31 | ||||
| public @interface BankCardDesensitize { | ||||
| } | ||||
| @@ -1,21 +0,0 @@ | ||||
| package cn.iocoder.yudao.framework.desensitize.annotation.constraints; | ||||
|  | ||||
| import cn.iocoder.yudao.framework.desensitize.annotation.SliderDesensitize; | ||||
| import com.fasterxml.jackson.annotation.JacksonAnnotationsInside; | ||||
|  | ||||
| import java.lang.annotation.Documented; | ||||
| import java.lang.annotation.ElementType; | ||||
| import java.lang.annotation.Retention; | ||||
| import java.lang.annotation.RetentionPolicy; | ||||
| import java.lang.annotation.Target; | ||||
|  | ||||
| /** | ||||
|  * 车牌号 | ||||
|  */ | ||||
| @Documented | ||||
| @Target({ElementType.FIELD}) | ||||
| @Retention(RetentionPolicy.RUNTIME) | ||||
| @JacksonAnnotationsInside | ||||
| @SliderDesensitize(prefixKeep = 3, suffixKeep = 1, replacer = "*") // 车牌号;比如:粤A66666脱敏之后为粤A6***6 | ||||
| public @interface CarLicenseDesensitize { | ||||
| } | ||||
| @@ -1,21 +0,0 @@ | ||||
| package cn.iocoder.yudao.framework.desensitize.annotation.constraints; | ||||
|  | ||||
| import cn.iocoder.yudao.framework.desensitize.annotation.SliderDesensitize; | ||||
| import com.fasterxml.jackson.annotation.JacksonAnnotationsInside; | ||||
|  | ||||
| import java.lang.annotation.Documented; | ||||
| import java.lang.annotation.ElementType; | ||||
| import java.lang.annotation.Retention; | ||||
| import java.lang.annotation.RetentionPolicy; | ||||
| import java.lang.annotation.Target; | ||||
|  | ||||
| /** | ||||
|  * 中文名 | ||||
|  */ | ||||
| @Documented | ||||
| @Target({ElementType.FIELD}) | ||||
| @Retention(RetentionPolicy.RUNTIME) | ||||
| @JacksonAnnotationsInside | ||||
| @SliderDesensitize(prefixKeep = 1, suffixKeep = 0, replacer = "*") // 中文名;比如:刘子豪脱敏之后为刘** | ||||
| public @interface ChineseNameDesensitize { | ||||
| } | ||||
| @@ -1,21 +0,0 @@ | ||||
| package cn.iocoder.yudao.framework.desensitize.annotation.constraints; | ||||
|  | ||||
| import cn.iocoder.yudao.framework.desensitize.annotation.RegexDesensitize; | ||||
| import com.fasterxml.jackson.annotation.JacksonAnnotationsInside; | ||||
|  | ||||
| import java.lang.annotation.Documented; | ||||
| import java.lang.annotation.ElementType; | ||||
| import java.lang.annotation.Retention; | ||||
| import java.lang.annotation.RetentionPolicy; | ||||
| import java.lang.annotation.Target; | ||||
|  | ||||
| /** | ||||
|  * 邮箱 | ||||
|  */ | ||||
| @Documented | ||||
| @Target({ElementType.FIELD}) | ||||
| @Retention(RetentionPolicy.RUNTIME) | ||||
| @JacksonAnnotationsInside | ||||
| @RegexDesensitize(regex = "(^.)[^@]*(@.*$)", replacer ="$1****$2")  // 邮箱;比如:example@gmail.com脱敏之后为e****@gmail.com | ||||
| public @interface EmailDesensitize { | ||||
| } | ||||
| @@ -1,21 +0,0 @@ | ||||
| package cn.iocoder.yudao.framework.desensitize.annotation.constraints; | ||||
|  | ||||
| import cn.iocoder.yudao.framework.desensitize.annotation.SliderDesensitize; | ||||
| import com.fasterxml.jackson.annotation.JacksonAnnotationsInside; | ||||
|  | ||||
| import java.lang.annotation.Documented; | ||||
| import java.lang.annotation.ElementType; | ||||
| import java.lang.annotation.Retention; | ||||
| import java.lang.annotation.RetentionPolicy; | ||||
| import java.lang.annotation.Target; | ||||
|  | ||||
| /** | ||||
|  * 固定电话 | ||||
|  */ | ||||
| @Documented | ||||
| @Target({ElementType.FIELD}) | ||||
| @Retention(RetentionPolicy.RUNTIME) | ||||
| @JacksonAnnotationsInside | ||||
| @SliderDesensitize(prefixKeep = 4, suffixKeep = 2, replacer = "*") // 固定电话;比如:01086551122脱敏之后为0108*****22 | ||||
| public @interface FixedPhoneDesensitize { | ||||
| } | ||||
| @@ -1,21 +0,0 @@ | ||||
| package cn.iocoder.yudao.framework.desensitize.annotation.constraints; | ||||
|  | ||||
| import cn.iocoder.yudao.framework.desensitize.annotation.SliderDesensitize; | ||||
| import com.fasterxml.jackson.annotation.JacksonAnnotationsInside; | ||||
|  | ||||
| import java.lang.annotation.Documented; | ||||
| import java.lang.annotation.ElementType; | ||||
| import java.lang.annotation.Retention; | ||||
| import java.lang.annotation.RetentionPolicy; | ||||
| import java.lang.annotation.Target; | ||||
|  | ||||
| /** | ||||
|  * 身份证 | ||||
|  */ | ||||
| @Documented | ||||
| @Target({ElementType.FIELD}) | ||||
| @Retention(RetentionPolicy.RUNTIME) | ||||
| @JacksonAnnotationsInside | ||||
| @SliderDesensitize(prefixKeep = 6, suffixKeep = 2, replacer = "*") // 身份证号码;比如:530321199204074611脱敏之后为530321**********11 | ||||
| public @interface IdCardDesensitize { | ||||
| } | ||||
| @@ -1,21 +0,0 @@ | ||||
| package cn.iocoder.yudao.framework.desensitize.annotation.constraints; | ||||
|  | ||||
| import cn.iocoder.yudao.framework.desensitize.annotation.SliderDesensitize; | ||||
| import com.fasterxml.jackson.annotation.JacksonAnnotationsInside; | ||||
|  | ||||
| import java.lang.annotation.Documented; | ||||
| import java.lang.annotation.ElementType; | ||||
| import java.lang.annotation.Retention; | ||||
| import java.lang.annotation.RetentionPolicy; | ||||
| import java.lang.annotation.Target; | ||||
|  | ||||
| /** | ||||
|  * 密码 | ||||
|  */ | ||||
| @Documented | ||||
| @Target({ElementType.FIELD}) | ||||
| @Retention(RetentionPolicy.RUNTIME) | ||||
| @JacksonAnnotationsInside | ||||
| @SliderDesensitize(prefixKeep = 0, suffixKeep = 0, replacer = "*") // 密码;比如:123456脱敏之后为****** | ||||
| public @interface PasswordDesensitize { | ||||
| } | ||||
| @@ -1,21 +0,0 @@ | ||||
| package cn.iocoder.yudao.framework.desensitize.annotation.constraints; | ||||
|  | ||||
| import cn.iocoder.yudao.framework.desensitize.annotation.SliderDesensitize; | ||||
| import com.fasterxml.jackson.annotation.JacksonAnnotationsInside; | ||||
|  | ||||
| import java.lang.annotation.Documented; | ||||
| import java.lang.annotation.ElementType; | ||||
| import java.lang.annotation.Retention; | ||||
| import java.lang.annotation.RetentionPolicy; | ||||
| import java.lang.annotation.Target; | ||||
|  | ||||
| /** | ||||
|  * 手机号 | ||||
|  */ | ||||
| @Documented | ||||
| @Target({ElementType.FIELD}) | ||||
| @Retention(RetentionPolicy.RUNTIME) | ||||
| @JacksonAnnotationsInside | ||||
| @SliderDesensitize(prefixKeep = 3, suffixKeep = 4, replacer = "*") // 手机号;比如:13248765917脱敏之后为132****5917 | ||||
| public @interface PhoneNumberDesensitize { | ||||
| } | ||||
| @@ -1,6 +1,9 @@ | ||||
| package cn.iocoder.yudao.framework.desensitize.handler; | ||||
| package cn.iocoder.yudao.framework.desensitize.core.base; | ||||
| 
 | ||||
| import cn.hutool.core.util.ReflectUtil; | ||||
| import cn.iocoder.yudao.framework.desensitize.core.base.handler.DesensitizationHandler; | ||||
| import cn.iocoder.yudao.framework.desensitize.core.regex.handler.DefaultRegexDesensitizationHandler; | ||||
| import cn.iocoder.yudao.framework.desensitize.core.slider.handler.DefaultDesensitizationHandler; | ||||
| 
 | ||||
| import java.util.Map; | ||||
| import java.util.concurrent.ConcurrentHashMap; | ||||
| @@ -13,8 +16,8 @@ public class DesensitizationHandlerHolder { | ||||
|      * handler 缓存,默认初始化内置的处理器 | ||||
|      */ | ||||
|     private static final Map<Class<? extends DesensitizationHandler>, DesensitizationHandler> HANDLER_MAP = new ConcurrentHashMap<>() {{ | ||||
|         put(RegexDesensitizationHandler.class, new RegexDesensitizationHandler()); | ||||
|         put(SliderDesensitizationHandler.class, new SliderDesensitizationHandler()); | ||||
|         put(DefaultRegexDesensitizationHandler.class, new DefaultRegexDesensitizationHandler()); | ||||
|         put(DefaultDesensitizationHandler.class, new DefaultDesensitizationHandler()); | ||||
|     }}; | ||||
| 
 | ||||
|     public static DesensitizationHandler getDesensitizationHandler(Class<? extends DesensitizationHandler> clazz) { | ||||
| @@ -1,6 +1,6 @@ | ||||
| package cn.iocoder.yudao.framework.desensitize.annotation; | ||||
| package cn.iocoder.yudao.framework.desensitize.core.base.annotation; | ||||
| 
 | ||||
| import cn.iocoder.yudao.framework.desensitize.handler.DesensitizationHandler; | ||||
| import cn.iocoder.yudao.framework.desensitize.core.base.handler.DesensitizationHandler; | ||||
| import cn.iocoder.yudao.framework.desensitize.serializer.StringDesensitizeSerializer; | ||||
| import com.fasterxml.jackson.annotation.JacksonAnnotationsInside; | ||||
| import com.fasterxml.jackson.databind.annotation.JsonSerialize; | ||||
| @@ -16,7 +16,7 @@ import java.lang.annotation.Target; | ||||
|  * Desensitize 顶级脱敏注解 | ||||
|  */ | ||||
| @Documented | ||||
| @Target({ElementType.FIELD, ElementType.ANNOTATION_TYPE}) | ||||
| @Target({ ElementType.ANNOTATION_TYPE}) | ||||
| @Retention(RetentionPolicy.RUNTIME) | ||||
| @JacksonAnnotationsInside | ||||
| @JsonSerialize(using = StringDesensitizeSerializer.class) | ||||
| @@ -25,6 +25,5 @@ public @interface Desensitize { | ||||
|     /** | ||||
|      * 脱敏处理器 | ||||
|      */ | ||||
|     Class<? extends DesensitizationHandler> desensitizationHandler(); | ||||
| 
 | ||||
|     Class<? extends DesensitizationHandler> desensitizationBy(); | ||||
| } | ||||
| @@ -0,0 +1,19 @@ | ||||
| package cn.iocoder.yudao.framework.desensitize.core.base.handler; | ||||
|  | ||||
| import java.lang.annotation.Annotation; | ||||
|  | ||||
| /** | ||||
|  * 脱敏处理器接口 | ||||
|  */ | ||||
| public interface DesensitizationHandler<T extends Annotation> { | ||||
|  | ||||
|     /** | ||||
|      * 脱敏 | ||||
|      * | ||||
|      * @param origin 原始字符串 | ||||
|      * @param anno   注解信息 | ||||
|      * @return 脱敏后的字符串 | ||||
|      */ | ||||
|     String desensitize(String origin, T anno); | ||||
|  | ||||
| } | ||||
| @@ -0,0 +1,34 @@ | ||||
| package cn.iocoder.yudao.framework.desensitize.core.regex.annotation; | ||||
|  | ||||
| import cn.iocoder.yudao.framework.desensitize.core.base.annotation.Desensitize; | ||||
| import cn.iocoder.yudao.framework.desensitize.core.regex.handler.EmailDesensitizationHandler; | ||||
| import com.fasterxml.jackson.annotation.JacksonAnnotationsInside; | ||||
|  | ||||
| import java.lang.annotation.Documented; | ||||
| import java.lang.annotation.ElementType; | ||||
| import java.lang.annotation.Retention; | ||||
| import java.lang.annotation.RetentionPolicy; | ||||
| import java.lang.annotation.Target; | ||||
|  | ||||
| /** | ||||
|  * 邮箱 | ||||
|  */ | ||||
| @Documented | ||||
| @Target({ElementType.FIELD}) | ||||
| @Retention(RetentionPolicy.RUNTIME) | ||||
| @JacksonAnnotationsInside | ||||
| @Desensitize(desensitizationBy = EmailDesensitizationHandler.class) // 邮箱;比如:example@gmail.com脱敏之后为e****@gmail.com | ||||
| public @interface EmailDesensitize { | ||||
|     /** | ||||
|      * 匹配的正则表达式(默认匹配所有) | ||||
|      */ | ||||
|     String regex() default  "(^.)[^@]*(@.*$)"; | ||||
|  | ||||
|     /** | ||||
|      * 替换规则,会将匹配到的字符串全部替换成 replacer | ||||
|      * 例如:regex=123; replacer=****** | ||||
|      * 原始字符串 123456789 | ||||
|      * 脱敏后字符串 ******456789 | ||||
|      */ | ||||
|     String replacer() default "$1****$2"; | ||||
| } | ||||
| @@ -1,6 +1,7 @@ | ||||
| package cn.iocoder.yudao.framework.desensitize.annotation; | ||||
| package cn.iocoder.yudao.framework.desensitize.core.regex.annotation; | ||||
| 
 | ||||
| import cn.iocoder.yudao.framework.desensitize.handler.RegexDesensitizationHandler; | ||||
| import cn.iocoder.yudao.framework.desensitize.core.base.annotation.Desensitize; | ||||
| import cn.iocoder.yudao.framework.desensitize.core.regex.handler.DefaultRegexDesensitizationHandler; | ||||
| import com.fasterxml.jackson.annotation.JacksonAnnotationsInside; | ||||
| 
 | ||||
| import java.lang.annotation.Documented; | ||||
| @@ -16,7 +17,7 @@ import java.lang.annotation.Target; | ||||
| @Target({ElementType.FIELD, ElementType.ANNOTATION_TYPE}) | ||||
| @Retention(RetentionPolicy.RUNTIME) | ||||
| @JacksonAnnotationsInside | ||||
| @Desensitize(desensitizationHandler = RegexDesensitizationHandler.class) | ||||
| @Desensitize(desensitizationBy = DefaultRegexDesensitizationHandler.class) | ||||
| public @interface RegexDesensitize { | ||||
|     /** | ||||
|      * 匹配的正则表达式(默认匹配所有) | ||||
| @@ -0,0 +1,25 @@ | ||||
| package cn.iocoder.yudao.framework.desensitize.core.regex.handler; | ||||
|  | ||||
| import cn.iocoder.yudao.framework.desensitize.core.base.handler.DesensitizationHandler; | ||||
|  | ||||
| import java.lang.annotation.Annotation; | ||||
|  | ||||
| public abstract class AbstractRegexDesensitizationHandler<T extends Annotation> implements DesensitizationHandler<T> { | ||||
|  | ||||
|     @Override | ||||
|     public String desensitize(String origin, T anno) { | ||||
|         Object[] args = getArgs(anno); | ||||
|         String regex = (String) args[0]; | ||||
|         String replacer = (String) args[1]; | ||||
|  | ||||
|         return origin.replaceAll(regex, replacer); | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * 获取注解的参数 | ||||
|      * | ||||
|      * @param anno 注解信息 | ||||
|      * @return 注解的参数 | ||||
|      */ | ||||
|     abstract Object[] getArgs(T anno); | ||||
| } | ||||
| @@ -0,0 +1,14 @@ | ||||
| package cn.iocoder.yudao.framework.desensitize.core.regex.handler; | ||||
|  | ||||
| import cn.iocoder.yudao.framework.desensitize.core.regex.annotation.RegexDesensitize; | ||||
|  | ||||
| /** | ||||
|  * 正则脱敏处理器 | ||||
|  */ | ||||
| public class DefaultRegexDesensitizationHandler extends AbstractRegexDesensitizationHandler<RegexDesensitize> { | ||||
|  | ||||
|     @Override | ||||
|     Object[] getArgs(RegexDesensitize anno) { | ||||
|         return new Object[]{anno.regex(), anno.replacer()}; | ||||
|     } | ||||
| } | ||||
| @@ -0,0 +1,11 @@ | ||||
| package cn.iocoder.yudao.framework.desensitize.core.regex.handler; | ||||
|  | ||||
| import cn.iocoder.yudao.framework.desensitize.core.regex.annotation.EmailDesensitize; | ||||
|  | ||||
| public class EmailDesensitizationHandler extends AbstractRegexDesensitizationHandler<EmailDesensitize> { | ||||
|  | ||||
|     @Override | ||||
|     Object[] getArgs(EmailDesensitize anno) { | ||||
|         return new Object[]{anno.regex(), anno.replacer()}; | ||||
|     } | ||||
| } | ||||
| @@ -0,0 +1,41 @@ | ||||
| package cn.iocoder.yudao.framework.desensitize.core.slider.annotation; | ||||
|  | ||||
| import cn.iocoder.yudao.framework.desensitize.core.base.annotation.Desensitize; | ||||
| import cn.iocoder.yudao.framework.desensitize.core.slider.handler.BankCardDesensitization; | ||||
| import com.fasterxml.jackson.annotation.JacksonAnnotationsInside; | ||||
|  | ||||
| import java.lang.annotation.Documented; | ||||
| import java.lang.annotation.ElementType; | ||||
| import java.lang.annotation.Retention; | ||||
| import java.lang.annotation.RetentionPolicy; | ||||
| import java.lang.annotation.Target; | ||||
|  | ||||
| /** | ||||
|  * 银行卡号 | ||||
|  */ | ||||
| @Documented | ||||
| @Target({ElementType.FIELD}) | ||||
| @Retention(RetentionPolicy.RUNTIME) | ||||
| @JacksonAnnotationsInside | ||||
| @Desensitize(desensitizationBy = BankCardDesensitization.class)// 银行卡号;比如:9988002866797031脱敏之后为998800********31 | ||||
| public @interface BankCard { | ||||
|  | ||||
|     /** | ||||
|      * 前缀保留长度 | ||||
|      */ | ||||
|     int prefixKeep() default 6; | ||||
|  | ||||
|     /** | ||||
|      * 后缀保留长度 | ||||
|      */ | ||||
|     int suffixKeep() default 2; | ||||
|  | ||||
|     /** | ||||
|      * 替换规则,会将前缀后缀保留后,全部替换成 replacer | ||||
|      * 例如:prefixKeep = 1; suffixKeep = 2; replacer = "*"; | ||||
|      * 原始字符串  123456 | ||||
|      * 脱敏后     1***56 | ||||
|      */ | ||||
|     String replacer() default "*"; | ||||
|  | ||||
| } | ||||
| @@ -0,0 +1,41 @@ | ||||
| package cn.iocoder.yudao.framework.desensitize.core.slider.annotation; | ||||
|  | ||||
| import cn.iocoder.yudao.framework.desensitize.core.base.annotation.Desensitize; | ||||
| import cn.iocoder.yudao.framework.desensitize.core.slider.handler.CarLicenseDesensitization; | ||||
| import com.fasterxml.jackson.annotation.JacksonAnnotationsInside; | ||||
|  | ||||
| import java.lang.annotation.Documented; | ||||
| import java.lang.annotation.ElementType; | ||||
| import java.lang.annotation.Retention; | ||||
| import java.lang.annotation.RetentionPolicy; | ||||
| import java.lang.annotation.Target; | ||||
|  | ||||
| /** | ||||
|  * 车牌号 | ||||
|  */ | ||||
| @Documented | ||||
| @Target({ElementType.FIELD}) | ||||
| @Retention(RetentionPolicy.RUNTIME) | ||||
| @JacksonAnnotationsInside | ||||
| @Desensitize(desensitizationBy = CarLicenseDesensitization.class) // 车牌号;比如:粤A66666脱敏之后为粤A6***6 | ||||
| public @interface CarLicense { | ||||
|  | ||||
|     /** | ||||
|      * 前缀保留长度 | ||||
|      */ | ||||
|     int prefixKeep() default 3; | ||||
|  | ||||
|     /** | ||||
|      * 后缀保留长度 | ||||
|      */ | ||||
|     int suffixKeep() default 1; | ||||
|  | ||||
|     /** | ||||
|      * 替换规则,会将前缀后缀保留后,全部替换成 replacer | ||||
|      * 例如:prefixKeep = 1; suffixKeep = 2; replacer = "*"; | ||||
|      * 原始字符串  123456 | ||||
|      * 脱敏后     1***56 | ||||
|      */ | ||||
|     String replacer() default "*"; | ||||
|  | ||||
| } | ||||
| @@ -0,0 +1,41 @@ | ||||
| package cn.iocoder.yudao.framework.desensitize.core.slider.annotation; | ||||
|  | ||||
| import cn.iocoder.yudao.framework.desensitize.core.base.annotation.Desensitize; | ||||
| import cn.iocoder.yudao.framework.desensitize.core.slider.handler.ChineseNameDesensitization; | ||||
| import com.fasterxml.jackson.annotation.JacksonAnnotationsInside; | ||||
|  | ||||
| import java.lang.annotation.Documented; | ||||
| import java.lang.annotation.ElementType; | ||||
| import java.lang.annotation.Retention; | ||||
| import java.lang.annotation.RetentionPolicy; | ||||
| import java.lang.annotation.Target; | ||||
|  | ||||
| /** | ||||
|  * 中文名 | ||||
|  */ | ||||
| @Documented | ||||
| @Target({ElementType.FIELD}) | ||||
| @Retention(RetentionPolicy.RUNTIME) | ||||
| @JacksonAnnotationsInside | ||||
| @Desensitize(desensitizationBy = ChineseNameDesensitization.class) // 中文名;比如:刘子豪脱敏之后为刘** | ||||
| public @interface ChineseName { | ||||
|  | ||||
|     /** | ||||
|      * 前缀保留长度 | ||||
|      */ | ||||
|     int prefixKeep() default 1; | ||||
|  | ||||
|     /** | ||||
|      * 后缀保留长度 | ||||
|      */ | ||||
|     int suffixKeep() default 0; | ||||
|  | ||||
|     /** | ||||
|      * 替换规则,会将前缀后缀保留后,全部替换成 replacer | ||||
|      * 例如:prefixKeep = 1; suffixKeep = 2; replacer = "*"; | ||||
|      * 原始字符串  123456 | ||||
|      * 脱敏后     1***56 | ||||
|      */ | ||||
|     String replacer() default "*"; | ||||
|  | ||||
| } | ||||
| @@ -0,0 +1,41 @@ | ||||
| package cn.iocoder.yudao.framework.desensitize.core.slider.annotation; | ||||
|  | ||||
| import cn.iocoder.yudao.framework.desensitize.core.base.annotation.Desensitize; | ||||
| import cn.iocoder.yudao.framework.desensitize.core.slider.handler.FixedPhoneDesensitization; | ||||
| import com.fasterxml.jackson.annotation.JacksonAnnotationsInside; | ||||
|  | ||||
| import java.lang.annotation.Documented; | ||||
| import java.lang.annotation.ElementType; | ||||
| import java.lang.annotation.Retention; | ||||
| import java.lang.annotation.RetentionPolicy; | ||||
| import java.lang.annotation.Target; | ||||
|  | ||||
| /** | ||||
|  * 固定电话 | ||||
|  */ | ||||
| @Documented | ||||
| @Target({ElementType.FIELD}) | ||||
| @Retention(RetentionPolicy.RUNTIME) | ||||
| @JacksonAnnotationsInside | ||||
| @Desensitize(desensitizationBy = FixedPhoneDesensitization.class) // 固定电话;比如:01086551122脱敏之后为0108*****22 | ||||
| public @interface FixedPhone { | ||||
|  | ||||
|     /** | ||||
|      * 前缀保留长度 | ||||
|      */ | ||||
|     int prefixKeep() default 4; | ||||
|  | ||||
|     /** | ||||
|      * 后缀保留长度 | ||||
|      */ | ||||
|     int suffixKeep() default 2; | ||||
|  | ||||
|     /** | ||||
|      * 替换规则,会将前缀后缀保留后,全部替换成 replacer | ||||
|      * 例如:prefixKeep = 1; suffixKeep = 2; replacer = "*"; | ||||
|      * 原始字符串  123456 | ||||
|      * 脱敏后     1***56 | ||||
|      */ | ||||
|     String replacer() default "*"; | ||||
|  | ||||
| } | ||||
| @@ -0,0 +1,41 @@ | ||||
| package cn.iocoder.yudao.framework.desensitize.core.slider.annotation; | ||||
|  | ||||
| import cn.iocoder.yudao.framework.desensitize.core.base.annotation.Desensitize; | ||||
| import cn.iocoder.yudao.framework.desensitize.core.slider.handler.IdCardDesensitization; | ||||
| import com.fasterxml.jackson.annotation.JacksonAnnotationsInside; | ||||
|  | ||||
| import java.lang.annotation.Documented; | ||||
| import java.lang.annotation.ElementType; | ||||
| import java.lang.annotation.Retention; | ||||
| import java.lang.annotation.RetentionPolicy; | ||||
| import java.lang.annotation.Target; | ||||
|  | ||||
| /** | ||||
|  * 身份证 | ||||
|  */ | ||||
| @Documented | ||||
| @Target({ElementType.FIELD}) | ||||
| @Retention(RetentionPolicy.RUNTIME) | ||||
| @JacksonAnnotationsInside | ||||
| @Desensitize(desensitizationBy = IdCardDesensitization.class) // 身份证号码;比如:530321199204074611脱敏之后为530321**********11 | ||||
| public @interface IdCard { | ||||
|  | ||||
|     /** | ||||
|      * 前缀保留长度 | ||||
|      */ | ||||
|     int prefixKeep() default 6; | ||||
|  | ||||
|     /** | ||||
|      * 后缀保留长度 | ||||
|      */ | ||||
|     int suffixKeep() default 2; | ||||
|  | ||||
|     /** | ||||
|      * 替换规则,会将前缀后缀保留后,全部替换成 replacer | ||||
|      * 例如:prefixKeep = 1; suffixKeep = 2; replacer = "*"; | ||||
|      * 原始字符串  123456 | ||||
|      * 脱敏后     1***56 | ||||
|      */ | ||||
|     String replacer() default "*"; | ||||
|  | ||||
| } | ||||
| @@ -0,0 +1,41 @@ | ||||
| package cn.iocoder.yudao.framework.desensitize.core.slider.annotation; | ||||
|  | ||||
| import cn.iocoder.yudao.framework.desensitize.core.base.annotation.Desensitize; | ||||
| import cn.iocoder.yudao.framework.desensitize.core.slider.handler.PasswordDesensitization; | ||||
| import com.fasterxml.jackson.annotation.JacksonAnnotationsInside; | ||||
|  | ||||
| import java.lang.annotation.Documented; | ||||
| import java.lang.annotation.ElementType; | ||||
| import java.lang.annotation.Retention; | ||||
| import java.lang.annotation.RetentionPolicy; | ||||
| import java.lang.annotation.Target; | ||||
|  | ||||
| /** | ||||
|  * 密码 | ||||
|  */ | ||||
| @Documented | ||||
| @Target({ElementType.FIELD}) | ||||
| @Retention(RetentionPolicy.RUNTIME) | ||||
| @JacksonAnnotationsInside | ||||
| @Desensitize(desensitizationBy = PasswordDesensitization.class) // 密码;比如:123456脱敏之后为****** | ||||
| public @interface Password { | ||||
|  | ||||
|     /** | ||||
|      * 前缀保留长度 | ||||
|      */ | ||||
|     int prefixKeep() default 0; | ||||
|  | ||||
|     /** | ||||
|      * 后缀保留长度 | ||||
|      */ | ||||
|     int suffixKeep() default 0; | ||||
|  | ||||
|     /** | ||||
|      * 替换规则,会将前缀后缀保留后,全部替换成 replacer | ||||
|      * 例如:prefixKeep = 1; suffixKeep = 2; replacer = "*"; | ||||
|      * 原始字符串  123456 | ||||
|      * 脱敏后     1***56 | ||||
|      */ | ||||
|     String replacer() default "*"; | ||||
|  | ||||
| } | ||||
| @@ -0,0 +1,41 @@ | ||||
| package cn.iocoder.yudao.framework.desensitize.core.slider.annotation; | ||||
|  | ||||
| import cn.iocoder.yudao.framework.desensitize.core.base.annotation.Desensitize; | ||||
| import cn.iocoder.yudao.framework.desensitize.core.slider.handler.PhoneNumberDesensitization; | ||||
| import com.fasterxml.jackson.annotation.JacksonAnnotationsInside; | ||||
|  | ||||
| import java.lang.annotation.Documented; | ||||
| import java.lang.annotation.ElementType; | ||||
| import java.lang.annotation.Retention; | ||||
| import java.lang.annotation.RetentionPolicy; | ||||
| import java.lang.annotation.Target; | ||||
|  | ||||
| /** | ||||
|  * 手机号 | ||||
|  */ | ||||
| @Documented | ||||
| @Target({ElementType.FIELD}) | ||||
| @Retention(RetentionPolicy.RUNTIME) | ||||
| @JacksonAnnotationsInside | ||||
| @Desensitize(desensitizationBy = PhoneNumberDesensitization.class) // 手机号;比如:13248765917脱敏之后为132****5917 | ||||
| public @interface PhoneNumber { | ||||
|  | ||||
|     /** | ||||
|      * 前缀保留长度 | ||||
|      */ | ||||
|     int prefixKeep() default 3; | ||||
|  | ||||
|     /** | ||||
|      * 后缀保留长度 | ||||
|      */ | ||||
|     int suffixKeep() default 4; | ||||
|  | ||||
|     /** | ||||
|      * 替换规则,会将前缀后缀保留后,全部替换成 replacer | ||||
|      * 例如:prefixKeep = 1; suffixKeep = 2; replacer = "*"; | ||||
|      * 原始字符串  123456 | ||||
|      * 脱敏后     1***56 | ||||
|      */ | ||||
|     String replacer() default "*"; | ||||
|  | ||||
| } | ||||
| @@ -1,6 +1,7 @@ | ||||
| package cn.iocoder.yudao.framework.desensitize.annotation; | ||||
| package cn.iocoder.yudao.framework.desensitize.core.slider.annotation; | ||||
| 
 | ||||
| import cn.iocoder.yudao.framework.desensitize.handler.SliderDesensitizationHandler; | ||||
| import cn.iocoder.yudao.framework.desensitize.core.base.annotation.Desensitize; | ||||
| import cn.iocoder.yudao.framework.desensitize.core.slider.handler.DefaultDesensitizationHandler; | ||||
| import com.fasterxml.jackson.annotation.JacksonAnnotationsInside; | ||||
| 
 | ||||
| import java.lang.annotation.Documented; | ||||
| @@ -16,8 +17,8 @@ import java.lang.annotation.Target; | ||||
| @Target({ElementType.FIELD, ElementType.ANNOTATION_TYPE}) | ||||
| @Retention(RetentionPolicy.RUNTIME) | ||||
| @JacksonAnnotationsInside | ||||
| @Desensitize(desensitizationHandler = SliderDesensitizationHandler.class) | ||||
| public @interface SliderDesensitize { | ||||
| @Desensitize(desensitizationBy = DefaultDesensitizationHandler.class) | ||||
| public @interface Slider { | ||||
| 
 | ||||
|     /** | ||||
|      * 后缀保留长度 | ||||
| @@ -1,17 +1,17 @@ | ||||
| package cn.iocoder.yudao.framework.desensitize.handler; | ||||
| package cn.iocoder.yudao.framework.desensitize.core.slider.handler; | ||||
| 
 | ||||
| import cn.iocoder.yudao.framework.desensitize.annotation.SliderDesensitize; | ||||
| import cn.iocoder.yudao.framework.desensitize.core.base.handler.DesensitizationHandler; | ||||
| 
 | ||||
| /** | ||||
|  * 滑动脱敏处理器 | ||||
|  */ | ||||
| public class SliderDesensitizationHandler implements DesensitizationHandler<SliderDesensitize> { | ||||
| import java.lang.annotation.Annotation; | ||||
| 
 | ||||
| public abstract class AbstractDesensitizationHandler<T extends Annotation> implements DesensitizationHandler<T> { | ||||
| 
 | ||||
|     @Override | ||||
|     public String desensitize(String origin, Object... arg) { | ||||
|         int prefixKeep = (Integer) arg[0]; | ||||
|         int suffixKeep = (Integer) arg[1]; | ||||
|         String replacer = (String) arg[2]; | ||||
|     public String desensitize(String origin, T anno) { | ||||
|         Object[] args = getArgs(anno); | ||||
|         int prefixKeep = (Integer) args[0]; | ||||
|         int suffixKeep = (Integer) args[1]; | ||||
|         String replacer = (String) args[2]; | ||||
| 
 | ||||
|         int length = origin.length(); | ||||
| 
 | ||||
| @@ -31,10 +31,13 @@ public class SliderDesensitizationHandler implements DesensitizationHandler<Slid | ||||
|                 origin.substring(prefixKeep + interval); | ||||
|     } | ||||
| 
 | ||||
|     @Override | ||||
|     public Object[] getAnnotationArgs(SliderDesensitize anno) { | ||||
|         return new Object[]{anno.prefixKeep(), anno.suffixKeep(), anno.replacer()}; | ||||
|     } | ||||
|     /** | ||||
|      * 获取注解的参数 | ||||
|      * | ||||
|      * @param anno 注解信息 | ||||
|      * @return 注解的参数 | ||||
|      */ | ||||
|     abstract Object[] getArgs(T anno); | ||||
| 
 | ||||
|     /** | ||||
|      * 根据长度循环构建替换符 | ||||
| @@ -0,0 +1,11 @@ | ||||
| package cn.iocoder.yudao.framework.desensitize.core.slider.handler; | ||||
|  | ||||
| import cn.iocoder.yudao.framework.desensitize.core.slider.annotation.BankCard; | ||||
|  | ||||
| public class BankCardDesensitization extends AbstractDesensitizationHandler<BankCard> { | ||||
|  | ||||
|     @Override | ||||
|     Object[] getArgs(BankCard anno) { | ||||
|         return new Object[]{anno.prefixKeep(), anno.suffixKeep(), anno.replacer()}; | ||||
|     } | ||||
| } | ||||
| @@ -0,0 +1,10 @@ | ||||
| package cn.iocoder.yudao.framework.desensitize.core.slider.handler; | ||||
|  | ||||
| import cn.iocoder.yudao.framework.desensitize.core.slider.annotation.CarLicense; | ||||
|  | ||||
| public class CarLicenseDesensitization  extends AbstractDesensitizationHandler<CarLicense> { | ||||
|     @Override | ||||
|     Object[] getArgs(CarLicense anno) { | ||||
|         return new Object[]{anno.prefixKeep(), anno.suffixKeep(), anno.replacer()}; | ||||
|     } | ||||
| } | ||||
| @@ -0,0 +1,10 @@ | ||||
| package cn.iocoder.yudao.framework.desensitize.core.slider.handler; | ||||
|  | ||||
| import cn.iocoder.yudao.framework.desensitize.core.slider.annotation.ChineseName; | ||||
|  | ||||
| public class ChineseNameDesensitization extends AbstractDesensitizationHandler<ChineseName> { | ||||
|     @Override | ||||
|     Object[] getArgs(ChineseName anno) { | ||||
|         return new Object[]{anno.prefixKeep(), anno.suffixKeep(), anno.replacer()}; | ||||
|     } | ||||
| } | ||||
| @@ -0,0 +1,14 @@ | ||||
| package cn.iocoder.yudao.framework.desensitize.core.slider.handler; | ||||
|  | ||||
| import cn.iocoder.yudao.framework.desensitize.core.slider.annotation.Slider; | ||||
|  | ||||
| /** | ||||
|  * 滑动脱敏处理器 | ||||
|  */ | ||||
| public class DefaultDesensitizationHandler extends AbstractDesensitizationHandler<Slider> { | ||||
|  | ||||
|     @Override | ||||
|     Object[] getArgs(Slider anno) { | ||||
|         return new Object[]{anno.prefixKeep(), anno.suffixKeep(), anno.replacer()}; | ||||
|     } | ||||
| } | ||||
| @@ -0,0 +1,10 @@ | ||||
| package cn.iocoder.yudao.framework.desensitize.core.slider.handler; | ||||
|  | ||||
| import cn.iocoder.yudao.framework.desensitize.core.slider.annotation.FixedPhone; | ||||
|  | ||||
| public class FixedPhoneDesensitization extends AbstractDesensitizationHandler<FixedPhone> { | ||||
|     @Override | ||||
|     Object[] getArgs(FixedPhone anno) { | ||||
|         return new Object[]{anno.prefixKeep(), anno.suffixKeep(), anno.replacer()}; | ||||
|     } | ||||
| } | ||||
| @@ -0,0 +1,10 @@ | ||||
| package cn.iocoder.yudao.framework.desensitize.core.slider.handler; | ||||
|  | ||||
| import cn.iocoder.yudao.framework.desensitize.core.slider.annotation.IdCard; | ||||
|  | ||||
| public class IdCardDesensitization  extends AbstractDesensitizationHandler<IdCard> { | ||||
|     @Override | ||||
|     Object[] getArgs(IdCard anno) { | ||||
|         return new Object[]{anno.prefixKeep(), anno.suffixKeep(), anno.replacer()}; | ||||
|     } | ||||
| } | ||||
| @@ -0,0 +1,10 @@ | ||||
| package cn.iocoder.yudao.framework.desensitize.core.slider.handler; | ||||
|  | ||||
| import cn.iocoder.yudao.framework.desensitize.core.slider.annotation.Password; | ||||
|  | ||||
| public class PasswordDesensitization extends AbstractDesensitizationHandler<Password> { | ||||
|     @Override | ||||
|     Object[] getArgs(Password anno) { | ||||
|         return new Object[]{anno.prefixKeep(), anno.suffixKeep(), anno.replacer()}; | ||||
|     } | ||||
| } | ||||
| @@ -0,0 +1,11 @@ | ||||
| package cn.iocoder.yudao.framework.desensitize.core.slider.handler; | ||||
|  | ||||
| import cn.iocoder.yudao.framework.desensitize.core.slider.annotation.PhoneNumber; | ||||
|  | ||||
| public class PhoneNumberDesensitization extends AbstractDesensitizationHandler<PhoneNumber> { | ||||
|  | ||||
|     @Override | ||||
|     Object[] getArgs(PhoneNumber anno) { | ||||
|         return new Object[]{anno.prefixKeep(), anno.suffixKeep(), anno.replacer()}; | ||||
|     } | ||||
| } | ||||
| @@ -1,28 +0,0 @@ | ||||
| package cn.iocoder.yudao.framework.desensitize.handler; | ||||
|  | ||||
| import java.lang.annotation.Annotation; | ||||
|  | ||||
| /** | ||||
|  * 脱敏处理器接口 | ||||
|  */ | ||||
| public interface DesensitizationHandler<T extends Annotation> { | ||||
|  | ||||
|     /** | ||||
|      * 脱敏 | ||||
|      * | ||||
|      * @param origin 原始字符串 | ||||
|      * @param arg    参数 | ||||
|      * @return 脱敏后的字符串 | ||||
|      */ | ||||
|     String desensitize(String origin, Object... arg); | ||||
|  | ||||
|     /** | ||||
|      * 获取注解参数 | ||||
|      * | ||||
|      * @param anno 注解 | ||||
|      * @return 注解参数 | ||||
|      */ | ||||
|     default Object[] getAnnotationArgs(T anno) { | ||||
|         return new Object[0]; | ||||
|     } | ||||
| } | ||||
| @@ -1,23 +0,0 @@ | ||||
| package cn.iocoder.yudao.framework.desensitize.handler; | ||||
|  | ||||
| import cn.iocoder.yudao.framework.desensitize.annotation.RegexDesensitize; | ||||
|  | ||||
| /** | ||||
|  * 正则脱敏处理器 | ||||
|  */ | ||||
| public class RegexDesensitizationHandler implements DesensitizationHandler<RegexDesensitize> { | ||||
|  | ||||
|     @Override | ||||
|     public String desensitize(String origin, Object... arg) { | ||||
|         String regex = (String) arg[0]; | ||||
|         String replacer = (String) arg[1]; | ||||
|  | ||||
|         return origin.replaceAll(regex, replacer); | ||||
|     } | ||||
|  | ||||
|     @Override | ||||
|     public Object[] getAnnotationArgs(RegexDesensitize anno) { | ||||
|         return new Object[]{anno.regex(), anno.replacer()}; | ||||
|     } | ||||
|  | ||||
| } | ||||
| @@ -4,11 +4,9 @@ import cn.hutool.core.annotation.AnnotationUtil; | ||||
| import cn.hutool.core.util.ArrayUtil; | ||||
| import cn.hutool.core.util.ReflectUtil; | ||||
| import cn.hutool.core.util.StrUtil; | ||||
| import cn.iocoder.yudao.framework.desensitize.annotation.Desensitize; | ||||
| import cn.iocoder.yudao.framework.desensitize.annotation.RegexDesensitize; | ||||
| import cn.iocoder.yudao.framework.desensitize.annotation.SliderDesensitize; | ||||
| import cn.iocoder.yudao.framework.desensitize.handler.DesensitizationHandler; | ||||
| import cn.iocoder.yudao.framework.desensitize.handler.DesensitizationHandlerHolder; | ||||
| import cn.iocoder.yudao.framework.desensitize.core.base.annotation.Desensitize; | ||||
| import cn.iocoder.yudao.framework.desensitize.core.base.handler.DesensitizationHandler; | ||||
| import cn.iocoder.yudao.framework.desensitize.core.base.DesensitizationHandlerHolder; | ||||
| import com.fasterxml.jackson.core.JsonGenerator; | ||||
| import com.fasterxml.jackson.databind.BeanProperty; | ||||
| import com.fasterxml.jackson.databind.JsonMappingException; | ||||
| @@ -46,7 +44,7 @@ public class StringDesensitizeSerializer extends StdSerializer<String> implement | ||||
|             return this; | ||||
|         } | ||||
|         StringDesensitizeSerializer serializer = new StringDesensitizeSerializer(); | ||||
|         serializer.setDesensitizationHandler(DesensitizationHandlerHolder.getDesensitizationHandler(annotation.desensitizationHandler())); | ||||
|         serializer.setDesensitizationHandler(DesensitizationHandlerHolder.getDesensitizationHandler(annotation.desensitizationBy())); | ||||
|         return serializer; | ||||
|     } | ||||
|  | ||||
| @@ -62,22 +60,6 @@ public class StringDesensitizeSerializer extends StdSerializer<String> implement | ||||
|         Class<?> currentValueClass = currentValue.getClass(); | ||||
|         Field field = ReflectUtil.getField(currentValueClass, currentName); | ||||
|  | ||||
|         // 滑动处理器 | ||||
|         SliderDesensitize sliderDesensitize = ArrayUtil.firstNonNull(AnnotationUtil.getCombinationAnnotations(field, SliderDesensitize.class)); | ||||
|         if (sliderDesensitize != null) { | ||||
|             value = this.desensitizationHandler.desensitize(value, this.desensitizationHandler.getAnnotationArgs(sliderDesensitize)); | ||||
|             gen.writeString(value); | ||||
|             return; | ||||
|         } | ||||
|  | ||||
|         // 正则处理器 | ||||
|         RegexDesensitize regexDesensitize = ArrayUtil.firstNonNull(AnnotationUtil.getCombinationAnnotations(field, RegexDesensitize.class)); | ||||
|         if (regexDesensitize != null) { | ||||
|             value = this.desensitizationHandler.desensitize(value, this.desensitizationHandler.getAnnotationArgs(regexDesensitize)); | ||||
|             gen.writeString(value); | ||||
|             return; | ||||
|         } | ||||
|  | ||||
|         // 自定义处理器 | ||||
|         Desensitize[] annotations = AnnotationUtil.getCombinationAnnotations(field, Desensitize.class); | ||||
|         if (ArrayUtil.isEmpty(annotations)) { | ||||
| @@ -86,8 +68,9 @@ public class StringDesensitizeSerializer extends StdSerializer<String> implement | ||||
|         } | ||||
|  | ||||
|         for (Annotation annotation : field.getAnnotations()) { | ||||
|  | ||||
|             if (AnnotationUtil.hasAnnotation(annotation.annotationType(), Desensitize.class)) { | ||||
|                 value = this.desensitizationHandler.desensitize(value, this.desensitizationHandler.getAnnotationArgs(annotation)); | ||||
|                 value = this.desensitizationHandler.desensitize(value, annotation); | ||||
|                 gen.writeString(value); | ||||
|                 return; | ||||
|             } | ||||
|   | ||||
| @@ -1,25 +0,0 @@ | ||||
| package cn.iocoder.yudao.framework.desensitize.handler; | ||||
|  | ||||
| import org.junit.jupiter.api.Assertions; | ||||
| import org.junit.jupiter.api.Test; | ||||
|  | ||||
| public class DesensitizationHandlerTest { | ||||
|  | ||||
|     @Test | ||||
|     public void testSliderDesensitizationHandler() { | ||||
|         DesensitizationHandler handler = DesensitizationHandlerHolder.getDesensitizationHandler(SliderDesensitizationHandler.class); | ||||
|  | ||||
|         Assertions.assertEquals("A****FG", handler.desensitize("ABCDEFG", 1, 2, "*")); | ||||
|         Assertions.assertEquals("芋**码", handler.desensitize("芋道源码", 1, 1, "*")); | ||||
|         Assertions.assertEquals("****", handler.desensitize("芋道源码", 4, 0, "*")); | ||||
|     } | ||||
|  | ||||
|     @Test | ||||
|     public void testRegexDesensitizationHandler() { | ||||
|         DesensitizationHandler handler = DesensitizationHandlerHolder.getDesensitizationHandler(RegexDesensitizationHandler.class); | ||||
|  | ||||
|         Assertions.assertEquals("e****@gmail.com", handler.desensitize("example@gmail.com", "(^.)[^@]*(@.*$)", "$1****$2")); | ||||
|         Assertions.assertEquals("***,铁***", handler.desensitize("他妈的,铁废物", "他妈的|去你大爷|卧槽|草泥马|废物", "***")); | ||||
|     } | ||||
|  | ||||
| } | ||||
		Reference in New Issue
	
	Block a user
	 gaibu
					gaibu