思路:如果我有一个复杂的对象,那么这个对象每个属性的值,我肯定是已知的,而且它的字段类型是已知的,字段的返回值是已知的,对象的类注解,字段的注解,方法的注解我都能拿到(利用反射)那么问题是不是就变的简单很多呢?
因为我可以利用注解,在我想要实现脱敏的字段上加上指定注解,然后最后拿到的value,利用反射给他set回去,那么这样是不是就实现了呢?下面看代码如何实现的!
代码:
@Target({ElementType.FIELD, ElementType.METHOD})
@Retention(RetentionPolicy.RUNTIME)
@Inherited
@documented
public @interface Desensitized {
SensitiveTypeEnum type();
String isEffictiveMethod() default "";
}
package com.danny.log.desensitized.entity;
import com.danny.log.desensitized.annotation.Desensitized;
import com.danny.log.desensitized.enums.SensitiveTypeEnum;
import java.math.BigDecimal;
import java.util.Date;
import java.util.List;
import java.util.Map;
public class baseUserInfo extends baseEntity{
private List
@Test
public void testUserInfo() throws IllegalAccessException, InstantiationException, InvocationTargetException, NoSuchMethodException {
List stringList = new ArrayList();
stringList.add("danny");
stringList.add("hoo");
stringList.add("song");
Map map=new HashMap();
map.put("dannymap",UserTypeEnum.ADMINISTRATOR);
Map map1=new HashMap();
map1.put("dannymap",UserTypeEnum.GENERAL);
Map map2=new HashMap();
map2.put("dannymap",UserTypeEnum.OPERATOR);
List mapList= new ArrayList<>();
mapList.add(map1);
mapList.add(map2);
mapList.add(map);
baseUserInfo baseUserInfo = new baseUserInfo()
.setRealName("胡丹尼")
.setIdCardNo("158199199013141120")
.setMobileNo("13579246810")
.setAccount("dannyhoo123456")
.setPassword("123456")
.setBankCardNo("6227000212090659057")
.setEmail("hudanni6688@126.com")
.setUserType(UserTypeEnum.ADMINISTRATOR)
.setUserService(new UserServiceImpl())
.setStrList(stringList)
.setMap(map)
.setiLimitKey(LimitFrequencyKeyEnum.SMSCODE_MOBILE_DAY_LIMIT)
.setMapList(mapList);
baseUserInfo.setId(101202L)
.setCreateTime(new Date())
.setUpdateTime(new Date());
UserPackage userPackage = new UserPackage()
.setFlag(true)
.setbaseUserInfo(baseUserInfo)
.setUserPackageName("UserPackageName_Danny");
System.out.println("脱敏前:" + JSON.toJSONString(baseUserInfo));
System.out.println("脱敏后:" + DesensitizedUtils.getJson(baseUserInfo));
System.out.println("嵌套实体脱敏后:" + DesensitizedUtils.getJson(userPackage));
}
public static String getJson(Object javaBean) {
String json = null;
if (null != javaBean) {
try {
if (javaBean.getClass().isInterface()) return json;
// Object clone =ObjectUtils.deepCloneObject(javaBean);
// Object clone =ObjectUtils.deepCloneByFastJson(javaBean);
// Object clone = ObjectUtils.deepClone(javaBean);
Object clone = ObjectUtils.MydeepClone(javaBean);
// System.out.println("clone:"+JSON.toJSonString(clone));
Set referenceCounter = new HashSet();
DesensitizedUtils.replace(ObjectUtils.getAllFields(clone), clone, referenceCounter);
json = JSON.toJSONString(clone, SerializerFeature.WriteMapNullValue, SerializerFeature.WriteNullListAsEmpty);
referenceCounter.clear();
referenceCounter = null;
} catch (Throwable e) {
e.printStackTrace();
}
}
return json;
}
private static void replace(Field[] fields, Object javaBean, SetreferenceCounter) throws IllegalArgumentException, IllegalAccessException { if (null != fields && fields.length > 0) { for (Field field : fields) { field.setAccessible(true); if (null != field && null != javaBean) { Object value = field.get(javaBean); if (null != value) { Class> type = value.getClass(); //处理子属性,包括集合中的 if (type.isArray()) {//对数组类型的字段进行递归过滤 int len = Array.getLength(value); for (int i = 0; i < len; i++) { Object arrayObject = Array.get(value, i); if (isNotGeneralType(arrayObject.getClass(), arrayObject, referenceCounter)) { replace(ObjectUtils.getAllFields(arrayObject), arrayObject, referenceCounter); } } } else if (value instanceof Collection>) {//对集合类型的字段进行递归过滤 Collection> c = (Collection>) value; Iterator> it = c.iterator(); while (it.hasNext()) {// TODO: 待优化 Object collectionObj = it.next(); if (isNotGeneralType(collectionObj.getClass(), collectionObj, referenceCounter)) { replace(ObjectUtils.getAllFields(collectionObj), collectionObj, referenceCounter); } } } else if (value instanceof Map, ?>) {//对Map类型的字段进行递归过滤 Map, ?> m = (Map, ?>) value; Set> set = m.entrySet(); for (Object o : set) { Map.Entry, ?> entry = (Map.Entry, ?>) o; Object mapVal = entry.getValue(); if (isNotGeneralType(mapVal.getClass(), mapVal, referenceCounter)) { replace(ObjectUtils.getAllFields(mapVal), mapVal, referenceCounter); } } } else if (value instanceof Enum>) { continue; } else { if (!type.isPrimitive() && type.getPackage() != null && !StringUtils.startsWith(type.getPackage().getName(), "javax.") && !StringUtils.startsWith(type.getPackage().getName(), "java.") && !StringUtils.startsWith(field.getType().getName(), "javax.") && !StringUtils.startsWith(field.getName(), "java.") && referenceCounter.add(value.hashCode())) { replace(ObjectUtils.getAllFields(value), value, referenceCounter); } } } //脱敏操作 setNewValueForField(javaBean, field, value); } } } }
public static void setNewValueForField(Object javaBean, Field field, Object value) throws IllegalAccessException {
//处理自身的属性
Desensitized annotation = field.getAnnotation(Desensitized.class);
if (field.getType().equals(String.class) && null != annotation && executeIsEffictiveMethod(javaBean, annotation)) {
String valueStr = (String) value;
if (StringUtils.isNotBlank(valueStr)) {
switch (annotation.type()) {
case CHINESE_NAME: {
field.set(javaBean, DesensitizedUtils.chineseName(valueStr));
break;
}
case ID_CARD: {
field.set(javaBean, DesensitizedUtils.idCardNum(valueStr));
break;
}
case FIXED_PHONE: {
field.set(javaBean, DesensitizedUtils.fixedPhone(valueStr));
break;
}
case MOBILE_PHONE: {
field.set(javaBean, DesensitizedUtils.mobilePhone(valueStr));
break;
}
case ADDRESS: {
field.set(javaBean, DesensitizedUtils.address(valueStr, 8));
break;
}
case EMAIL: {
field.set(javaBean, DesensitizedUtils.email(valueStr));
break;
}
case BANK_CARD: {
field.set(javaBean, DesensitizedUtils.bankCard(valueStr));
break;
}
case PASSWORD: {
field.set(javaBean, DesensitizedUtils.password(valueStr));
break;
}
}
}
}
}



