package com.github.tools.pub; import com.alibaba.fastjson.JSONArray; import com.alibaba.fastjson.JSONObject; import com.alibaba.fastjson.annotation.JSONField; import com.github.tools.annotation.HideAnn; import com.github.tools.annotation.HideCollection; import com.github.tools.annotation.HideImg; import java.lang.reflect.Field; import java.lang.reflect.Modifier; import java.util.*; /** * 日志格式化工具类,可用于隐藏base64字符串,隐藏password等一些敏感信息输出 * @Author: renhongqiang * @Date: 2020/5/12 3:51 下午 **/ public final class LogFormats { private LogFormats() {} private static final String HIDE_PWD = "*******"; private static final String UNKNOWN = "unknown"; private static final String SERIAL_VERSION_UID = "serialVersionUID"; /** * 过滤obj中敏感属性 */ public static String formatLog(Object obj) { if (Checks.isEmpty(obj)) { return "null"; } //隐藏注解项 JSONObject jsonObject = handleObjectJSON(obj); if (jsonObject != null) { return jsonObject.toJSONString(); } //else return JSONObject.toJSONString(obj); } /** * 处理object 返回json对象 */ private static JSONObject handleObjectJSON(Object target) { try { Object jsObj = JSONObject.toJSON(target); //数组json if (jsObj instanceof JSONArray) { ObjectBean objectBean = new ObjectBean(target); return handleObjectJSON(objectBean); } //对象json if (jsObj instanceof JSONObject) { JSONObject objCopy = (JSONObject) (jsObj); List<Field> objFields = getFieldListByClass(target.getClass()); for (Field field : objFields) { field.setAccessible(true); Object fieldVal = field.get(target); hideProperties(objCopy, field, fieldVal);//敏感信息隐藏 } return objCopy; } } catch (Exception e) { e.printStackTrace(); } //else return null; } /** * 敏感信息隐藏 */ private static void hideProperties(JSONObject objCopy, Field field, Object fieldVal) { if (isBasicType(fieldVal)) { //基本类型 handleBasicType(objCopy, field, fieldVal); } else if (fieldVal instanceof Collection) { //Collection类型 handleCollectionType(objCopy, field, fieldVal); } else if (fieldVal instanceof Map) { //Map类型 handleMapType(objCopy, field, fieldVal); } else if (Checks.isArray(fieldVal)) { //数组类型 handleArrayType(objCopy, field, fieldVal); } else { String fieldName = null; if (hasJSONField(field)) { fieldName = getJSONFieldName(field); } else { fieldName = field.getName(); } //对象类型 JSONObject jsonObject = handleObjectJSON(fieldVal); objCopy.put(fieldName, jsonObject); } } /** * 处理数组类型 */ private static void handleArrayType(JSONObject objCopy, Field field, Object fieldVal) { Object[] objects = (Object[]) fieldVal; String fieldName = null; if (hasJSONField(field)) { fieldName = getJSONFieldName(field); } else { fieldName = field.getName(); } if (hasHideCollection(field)) { JSONArray array = new JSONArray(); int length = objects.length; if (length > 0) { //取一个 array.add(handleType(objects[0])); array.add(hideArrays(length)); } objCopy.put(fieldName, array); } else { JSONArray array = new JSONArray(); for (Object item : objects) { array.add(handleType(item)); } objCopy.put(fieldName, array); } } /** * 处理Map 类型 */ private static void handleMapType(JSONObject objCopy, Field field, Object fieldVal) { Map map = (Map) fieldVal; String fieldName = null; if (hasJSONField(field)) { fieldName = getJSONFieldName(field); } else { fieldName = field.getName(); } if (hasHideCollection(field)) { int size = map.size(); JSONObject jsonObj = hideArrays(size); if (size > 0) { //取一个 Map.Entry<Object, Object> next = (Map.Entry<Object, Object>) map.entrySet().iterator().next(); Object key = next.getKey(); Object item = next.getValue(); jsonObj.put(key.toString(), handleType(item)); } objCopy.put(fieldName, jsonObj); } else { JSONObject jsonObj = new JSONObject(); for (Map.Entry<Object, Object> objectEntry : (Set<Map.Entry<Object, Object>>) (map.entrySet())) { Object key = objectEntry.getKey(); Object item = objectEntry.getValue(); jsonObj.put(key.toString(), handleType(item)); } objCopy.put(fieldName, jsonObj); } } /** * 处理集合类型 */ private static void handleCollectionType(JSONObject objCopy, Field field, Object fieldVal) { Collection objCollection = (Collection) fieldVal; String fieldName = null; if (hasJSONField(field)) { fieldName = getJSONFieldName(field); } else { fieldName = field.getName(); } if (hasHideCollection(field)) { int size = objCollection.size(); JSONArray array = new JSONArray(); if (size > 0) { //取一个 Object next = objCollection.iterator().next(); array.add(handleType(next)); array.add(hideArrays(size)); } objCopy.put(fieldName, array); } else { JSONArray array = new JSONArray(); for (Object item : objCollection) { array.add(handleType(item)); } objCopy.put(fieldName, array); } } /** * 处理基本类型 */ private static void handleBasicType(JSONObject objCopy, Field field, Object fieldVal) { //如果是序列化ID if(field.getName().equals(SERIAL_VERSION_UID)&& Modifier.isStatic(field.getModifiers())&& Modifier.isFinal(field.getModifiers())&&field.getType().getTypeName().equalsIgnoreCase("long")){ return; } //基本类型 int length = fieldVal.toString().length(); String fieldName = null; if (hasJSONField(field)) { fieldName = getJSONFieldName(field); } else { fieldName = field.getName(); } if ((hasHideImg(field))) { String front = Strings.substring((fieldVal.toString()), 0, 23); String after = Strings.substring((fieldVal.toString()), length - 11, length - 1); objCopy.put(fieldName, front + HIDE_PWD + after); } else if ((hasHideAn(field))) { objCopy.put(fieldName, HIDE_PWD); } else { objCopy.put(fieldName, fieldVal); } } /** * 隐藏集合对象,只显示第一条内容 */ private static JSONObject hideArrays(int size) { JSONObject jsonObject = new JSONObject(); jsonObject.put("message", "collection total size is " + size); return jsonObject; } /** * 非基本类型继续format */ private static Object handleType(Object target) { if (!isBasicType(target)) { return handleObjectJSON(target); } return target; } /** * 获取类以及父类属性 */ private static List<Field> getFieldListByClass(Class<?> clazz) { List<Field> fieldList = new ArrayList<>(); while (clazz != null) { fieldList.addAll(Arrays.asList(clazz.getDeclaredFields())); clazz = clazz.getSuperclass(); } return fieldList; } private static boolean hasHideImg(Field field) { return field.getAnnotation(HideImg.class) != null; } private static boolean hasJSONField(Field field) { return field.getAnnotation(JSONField.class) != null; } private static String getJSONFieldName(Field field) { JSONField annotation = field.getAnnotation(JSONField.class); if(annotation!=null){ return annotation.name(); } return UNKNOWN; } private static boolean hasHideAn(Field field) { return field.getAnnotation(HideAnn.class) != null; } private static boolean hasHideCollection(Field field) { return field.getAnnotation(HideCollection.class) != null; } /** * 判断是否为基本类型 */ private static boolean isBasicType(Object obj) { return (obj instanceof CharSequence || obj instanceof Boolean || obj instanceof Number || obj instanceof Character); } public static class ObjectBean { private Object arrayObject; public ObjectBean() { } public ObjectBean(Object arrayObject) { this.arrayObject = arrayObject; } public Object getArrayObject() { return arrayObject; } public void setArrayObject(Object arrayObject) { this.arrayObject = arrayObject; } } }