feat: 支持 vo 返回的脱敏
This commit is contained in:
parent
61a34ddac5
commit
c60f8d6da2
|
@ -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("他妈的,铁废物", "他妈的|去你大爷|卧槽|草泥马|废物", "***"));
|
||||
}
|
||||
|
||||
}
|
Loading…
Reference in New Issue