一共两种用法
(1) 在实体类使用
(2)在有返回值的方法上使用
package com.hmdp.aop.annotation;
import com.hmdp.constant.SensitiveType;
import java.lang.annotation.*;
/**
* @Author: ldj
* @Date: 2024/03/28/10:22
* @Description: 敏感字段注解
*/
@Retention(RetentionPolicy.RUNTIME)
@Target({ElementType.FIELD,ElementType.METHOD})
@Documented
public @interface Desensitized {
/**
* 脱敏数据类型
*/
SensitiveType type() default SensitiveType.CUSTOMER;
/**
* 方法返回值字段脱敏 配置规则 字段名_左不覆盖索引_右不覆盖索引,如password_0_0
*/
String[] rules() default {};
}
package com.hmdp.aop.aspect;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.hmdp.aop.annotation.Desensitized;
import com.hmdp.utils.DesensitizedUtil;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.reflect.MethodSignature;
import org.springframework.core.annotation.AnnotationUtils;
import org.springframework.stereotype.Component;
import java.util.Arrays;
/**
* @Author: ldj
* @Date: 2024/03/28/14:15
* @Description: 去敏切面
*/
@Aspect
@Component
public class DesensitizedAspect {
@Around("@annotation(com.hmdp.aop.annotation.Desensitized)")
public Object desensitize(ProceedingJoinPoint joinPoint) throws Throwable {
//前置处理
Object[] args = joinPoint.getArgs();
System.out.println(Arrays.toString(args));
//执行目标方法
Object obj = joinPoint.proceed();
//后置处理
MethodSignature signature = (MethodSignature) joinPoint.getSignature();
Desensitized annotation = AnnotationUtils.getAnnotation(signature.getMethod(), Desensitized.class);
assert annotation != null;
String[] rules = annotation.rules();
JSONObject jsonObject = JSONObject.parseObject(JSON.toJSONString(obj));
for (String rule : rules) {
//password_0_0
String[] split = rule.split("_");
String fieldName = split[0];
String value = (String) jsonObject.get(fieldName);
//去敏
value = DesensitizedUtil.cover(value, Integer.parseInt(split[1]), Integer.parseInt(split[2]), "*");
jsonObject.put(fieldName, value);
}
return jsonObject.toJavaObject(obj.getClass());
}
}
package com.hmdp.utils;
import com.hmdp.aop.annotation.Desensitized;
import com.hmdp.constant.SensitiveType;
import com.hmdp.entity.User;
import org.apache.commons.lang3.StringUtils;
import java.lang.reflect.Field;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import static com.hmdp.constant.SensitiveType.*;
/**
* @Author: ldj
* @Date: 2024/03/28/9:26
* @Description: 脱敏工具类
*/
public class DesensitizedUtil<T> {
//单个对象
public static <T> T desensitize(T t) throws IllegalAccessException {
List<Field> sensitiveFields = getSensitiveField(t.getClass());
for (Field sensitiveField : sensitiveFields) {
Desensitized annotation = sensitiveField.getAnnotation(Desensitized.class);
SensitiveType sensitiveType = annotation.type();
sensitiveField.setAccessible(true);
String value = (String) sensitiveField.get(t);
String maskValue = convertByType(value, sensitiveType);
sensitiveField.set(t, maskValue);
}
return t;
}
//多个对象
public static <T> List<T> desensitizes(List<T> ts) throws IllegalAccessException {
List<T> list = new ArrayList<>();
for (T t : ts) {
list.add(desensitize(t));
}
return list;
}
private static <T> List<Field> getSensitiveField(Class<T> clazz) {
List<Field> tempList = new ArrayList<>();
tempList.addAll(Arrays.asList(clazz.getSuperclass().getDeclaredFields()));
tempList.addAll(Arrays.asList(clazz.getDeclaredFields()));
List<Field> fields = new ArrayList<>();
for (Field field : tempList) {
if (field.isAnnotationPresent(Desensitized.class)) {
fields.add(field);
}
}
return fields;
}
private static String convertByType(String value, SensitiveType sensitiveType) {
switch (sensitiveType) {
case CUSTOMER:
value = cover(value, CUSTOMER.getPrefixNoMaskLen(), CUSTOMER.getSuffixNoMaskLen(), "*");
break;
case CHINESE_NAME:
value = cover(value, CHINESE_NAME.getPrefixNoMaskLen(), CHINESE_NAME.getSuffixNoMaskLen(), "*");
break;
case ID_CARD_NUM:
value = cover(value, ID_CARD_NUM.getPrefixNoMaskLen(), ID_CARD_NUM.getSuffixNoMaskLen(), "*");
break;
case MOBILE_PHONE:
value = cover(value, MOBILE_PHONE.getPrefixNoMaskLen(), ID_CARD_NUM.getSuffixNoMaskLen(), "*");
break;
case FIXED_PHONE:
value = cover(value, FIXED_PHONE.getPrefixNoMaskLen(), FIXED_PHONE.getSuffixNoMaskLen(), "*");
break;
case PASSWORD:
value = cover(value, PASSWORD.getPrefixNoMaskLen(), PASSWORD.getSuffixNoMaskLen(), "*");
break;
case BANKCARD:
value = cover(value, BANKCARD.getPrefixNoMaskLen(), BANKCARD.getSuffixNoMaskLen(), "*");
break;
case EMAIL:
value = cover(value, EMAIL.getPrefixNoMaskLen(), EMAIL.getSuffixNoMaskLen(), "*");
break;
case ADDRESS:
value = cover(value, ADDRESS.getPrefixNoMaskLen(), ADDRESS.getSuffixNoMaskLen(), "*");
break;
}
return value;
}
// public static String cover2(String origin, int prefixNoMaskLen, int suffixNoMaskLen, String maskStr) {
// if (origin == null) {
// return null;
// }
//
// StringBuilder sb = new StringBuilder();
// for (int i = 0, n = origin.length(); i < n; i++) {
// if (i < prefixNoMaskLen) {
// sb.append(origin.charAt(i));
// continue;
// }
// if (i > (n - suffixNoMaskLen - 1)) {
// sb.append(origin.charAt(i));
// continue;
// }
// sb.append(maskStr);
// }
// return sb.toString();
// }
public static String cover(String s, int prefixNoMaskLen, int suffixNoMaskLen, String symbol) {
if (StringUtils.isBlank(s)) {
return "";
}
if (StringUtils.isBlank(symbol)) {
symbol = "*";
}
int length = s.length();
if (length > prefixNoMaskLen + suffixNoMaskLen) {
String prefix = StringUtils.left(s, prefixNoMaskLen);
String suffix = StringUtils.right(s, suffixNoMaskLen);
s = StringUtils.rightPad(prefix, StringUtils.length(s) - suffixNoMaskLen, symbol).concat(suffix);
}
return s;
}
public static void main(String[] args) throws IllegalAccessException {
User user1 = new User().setPhone("13588833061").setPassword("wdergr4594fe!");
User user2 = new User().setPhone("13599933061").setPassword("wdergr5464fe!");
User user = DesensitizedUtil.desensitize(user1);
System.out.println(user1.toString());
List<User> desensitizes = DesensitizedUtil.desensitizes(Arrays.asList(user1, user2));
System.out.println(desensitizes);
}
}
package com.hmdp.constant;
/**
* @Author: ldj
* @Date: 2024/03/28/9:50
* @Description: 字段敏感类型
*/
public enum SensitiveType {
/**
* 自定义
*/
CUSTOMER(0,0),
/**
* 名称
**/
CHINESE_NAME(1,0),
/**
* 身份证证件号
**/
ID_CARD_NUM(0,4),
/**
* 手机号
**/
MOBILE_PHONE(3,4),
/**
* 固定电话
*/
FIXED_PHONE(0,4),
/**
* 密码
**/
PASSWORD(0,0),
/**
* 银行卡号
*/
BANKCARD(6,4),
/**
* 邮箱
*/
EMAIL(1,4),
/**
* 地址
*/
ADDRESS(9,0);
private int prefixNoMaskLen;
private int suffixNoMaskLen;
SensitiveType(int prefixNoMaskLen,int suffixNoMaskLen){
this.prefixNoMaskLen = prefixNoMaskLen;
this.suffixNoMaskLen = suffixNoMaskLen;
}
public int getPrefixNoMaskLen() {
return prefixNoMaskLen;
}
public void setPrefixNoMaskLen(int prefixNoMaskLen) {
this.prefixNoMaskLen = prefixNoMaskLen;
}
public int getSuffixNoMaskLen() {
return suffixNoMaskLen;
}
public void setSuffixNoMaskLen(int suffixNoMaskLen) {
this.suffixNoMaskLen = suffixNoMaskLen;
}
}