日志脱敏(不需要jar)

   其实也可以使用相关jar去处理,现在这个讲的是不用jar包的方式,本质都一样

 @GetMapping(value = "/user")
 @ResponseBody
  public List<Person> getUser(String cerno){
      List<Person> getList = new ArrayList<>();
      List<Integer> list = new ArrayList<>();
      list.add(Integer.valueOf(cerno));
      //QueryUtil.Query 只能查询单表的
      //List<Person> query = QueryUtil.Query(Person.class, "select s.* from person s where s.idNo = ?",list.toArray());
      //这个Query 在日志脱敏先不要管,只要出现出来用List接收就行
      List<Person> query = QueryUtil.Query(Person.class, "select * from person");
      query.forEach(a->{
          String converent = DesensitizedUtils.getConverent((Map<String,Object>)JSON.toJSON(a));
          Person person = JSON.parseObject(converent, Person.class);
          getList.add(person);
      });

      return getList;
  }

实体类不需要动

@Data
public class Person implements Serializable {

    private String custName;

    private int idNo;

    private String certNo;
}

自定义注解

@Target({ElementType.METHOD,ElementType.FIELD})
@Retention(RetentionPolicy.RUNTIME)
@Inherited
@Documented
public @interface DesensitizedAnnotation {
    /*脱敏数据类型(规则)*/
    TypeEnum type();
    /*判断注解是否生效,暂时没有用到*/
    String isEffictiveMethod() default "";

}
public class BaseInfo implements Serializable {

    private static final long serialVersionUID = 1L;

    @DesensitizedAnnotation(type = TypeEnum.PERSON_NAME)
    private String custName;

    @DesensitizedAnnotation(type = TypeEnum.PERSON_CERT_NO)
    private String certNo;
}

工具类(处理逻辑放这里)

public class DesensitizedUtils {
    
        private static final Logger logger = LoggerFactory.getLogger(DesensitizedUtils.class);
    
        private static final Map<String, TypeEnum> annotationMaps = new HashMap<>();
    
        /**
         * 类加载时装配待脱敏字段
         */
        static {
            try {
                Class<?> clazz = Class.forName(BaseInfo.class.getName());
                Field[] fields = clazz.getDeclaredFields();
                for (int i = 0; i < fields.length; i++) {
                    fields[i].setAccessible(true);
                    DesensitizedAnnotation annotation = fields[i].getAnnotation(DesensitizedAnnotation.class);
                    if (annotation != null) {
                        TypeEnum type = annotation.type();
                        String name = fields[i].getName();
                        //name为注解字段名称,value为注解类型。方便后续根据注解类型扩展
                        annotationMaps.put(name, type);
                    }
                }
            } catch (ClassNotFoundException e) {
                e.printStackTrace();
                logger.error("类加载时装配待脱敏字段异常,异常信息:[{}]", new Object[]{e});
            }
        }
    
    
        /**
         * 脱敏处理方法
         *
         * @param object
         * @return
         */
        public static String getConverent(Object object) {
    
            String objClassName = object.getClass().getName();
    
            try {
                // 1.处理Map数据类型
                if (object instanceof Map) {
                    //HashMap<String, Object> reqMap = (HashMap) object;
                    Map<String, Object> reqMap = (Map<String, Object>) object;
                    Iterator<String> iterator = annotationMaps.keySet().iterator();
                    iterator.forEachRemaining(annotationName -> {
                        if (reqMap.keySet().contains(annotationName)) {
                            doconverentForMap(reqMap, annotationName);
                        }
                    });
                    return JSON.toJSONString(reqMap);
                }
                // 2.处理Object数据类型
                Object val = new Object();
                Class<?> objClazz = Class.forName(objClassName);
                Field[] declaredFields = objClazz.getDeclaredFields();
                for (int j = 0; j < declaredFields.length; j++) {
                    Iterator<String> iterator = annotationMaps.keySet().iterator();
                    while (iterator.hasNext()) {
                        String annotationName = iterator.next();
                        if (declaredFields[j].getName().equals(annotationName)) {
                            declaredFields[j].setAccessible(true);
                            val = declaredFields[j].get(object);
                            //获取属性后现在默认处理的是String类型,其他类型数据可扩展
                            String value = doconverentForObject(val, annotationName);
                            declaredFields[j].set(object, value);
                        }
                    }
                }
                return JSON.toJSONString(object);
            } catch (Exception e) {
                e.printStackTrace();
                logger.error("日志脱敏处理失败,回滚,详细信息:[{}]", new Object[]{e});
                return JSON.toJSONString(object);
            }
        }
    
        /**
         * 脱敏数据源为Object时处理方式
         *
         * @param val
         * @param annotationName
         * @return
         */
        private static String doconverentForObject(Object val, String annotationName) {
    
            String value = String.valueOf(val);
            if (!StringUtils.isEmpty(value)) {
                value = doConverentByType(value, annotationName);
            }
            return value;
        }
    
        /**
         * 脱敏数据源为Map时处理方式
         *
         * @param reqMap
         * @param annotationName
         * @return
         */
        private static void doconverentForMap(Map<String, Object> reqMap, String annotationName) {
            String value = String.valueOf(reqMap.get(annotationName));
            if (!StringUtils.isEmpty(value)) {
                value = doConverentByType(value, annotationName);
            }
            reqMap.put(annotationName, value);
        }
    
    
        /**
         * 根据不同注解类型处理不同字段
         *
         * @param value
         * @param annotationName
         * @return
         */
        private static String doConverentByType(String value, String annotationName) {
            TypeEnum typeEnum = annotationMaps.get(annotationName);
            switch (typeEnum) {
                case PERSON_NAME:
                    value = getStringByLength(value);
                    break;
                case PERSON_CERT_NO:
                    value = getStringByLength(value);
                default:
                    value = getStringByLength(value);
            }
            return value;
        }
    
        /**
         * 根据value长度取值(切分)
         *
         * @param value
         * @return
         */
        private static String getStringByLength(String value) {
            int length = value.length();
            if (length == 2){
                value = value.substring(0, 1) + "*";
            }else if (length == 3){
                value = value.substring(0,1) + "*" + value.substring(length -1);
            }else if (length > 3 && length <= 5){
                value = value.substring(0,1) + "**" + value.substring(length -2);
            }else if (length > 5 && length <= 7){
                value = value.substring(0,2) + "***" + value.substring(length -2);
            }else if (length > 7){
                value = value.substring(0,3) + "*****" + value.substring(length -3);
            }
            return value;
        }
    
    }

输出结果:

    [
	    {
	        "custName": "11e*****ejj",
	            "idNo": 1,
	            "certNo": "122*****991"
	    },
	    {
	        "custName": "999*****999",
	            "idNo": 2,
	            "certNo": "185*****205"
	    }
    ]
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值