update 优化日志参数字段排除处理 采用更好的JsonNode节点树处理 性能更好
This commit is contained in:
+42
@@ -10,6 +10,7 @@ import org.dromara.common.core.utils.StringUtils;
|
|||||||
import tools.jackson.core.type.TypeReference;
|
import tools.jackson.core.type.TypeReference;
|
||||||
import tools.jackson.databind.JsonNode;
|
import tools.jackson.databind.JsonNode;
|
||||||
import tools.jackson.databind.json.JsonMapper;
|
import tools.jackson.databind.json.JsonMapper;
|
||||||
|
import tools.jackson.databind.node.ObjectNode;
|
||||||
|
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
@@ -138,6 +139,47 @@ public class JsonUtils {
|
|||||||
return JSON_MAPPER.readValue(text, JSON_MAPPER.getTypeFactory().constructCollectionType(List.class, clazz));
|
return JSON_MAPPER.readValue(text, JSON_MAPPER.getTypeFactory().constructCollectionType(List.class, clazz));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 将对象转换为 JSON 字符串,并递归移除指定字段。
|
||||||
|
*
|
||||||
|
* @param object 要转换的对象
|
||||||
|
* @param fieldNames 需要移除的字段名
|
||||||
|
* @return 移除字段后的 JSON 字符串
|
||||||
|
*/
|
||||||
|
public static String toJsonStringExcludeFields(Object object, String... fieldNames) {
|
||||||
|
if (ObjectUtil.isNull(object)) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
JsonNode node = JSON_MAPPER.valueToTree(object);
|
||||||
|
removeFields(node, fieldNames);
|
||||||
|
return toJsonString(node);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 从 JSON 树中递归移除指定字段。
|
||||||
|
*
|
||||||
|
* @param node JSON 节点
|
||||||
|
* @param fieldNames 需要移除的字段名
|
||||||
|
* @return 原 JSON 节点
|
||||||
|
*/
|
||||||
|
public static JsonNode removeFields(JsonNode node, String... fieldNames) {
|
||||||
|
if (node == null || ArrayUtil.isEmpty(fieldNames)) {
|
||||||
|
return node;
|
||||||
|
}
|
||||||
|
if (node.isObject()) {
|
||||||
|
ObjectNode objectNode = (ObjectNode) node;
|
||||||
|
for (String fieldName : fieldNames) {
|
||||||
|
if (StringUtils.isNotBlank(fieldName)) {
|
||||||
|
objectNode.remove(fieldName);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
for (JsonNode child : node) {
|
||||||
|
removeFields(child, fieldNames);
|
||||||
|
}
|
||||||
|
return node;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 判断字符串是否为合法 JSON(对象或数组)
|
* 判断字符串是否为合法 JSON(对象或数组)
|
||||||
*
|
*
|
||||||
|
|||||||
+1
-34
@@ -1,6 +1,5 @@
|
|||||||
package org.dromara.common.log.aspect;
|
package org.dromara.common.log.aspect;
|
||||||
|
|
||||||
import cn.hutool.core.lang.Dict;
|
|
||||||
import cn.hutool.core.map.MapUtil;
|
import cn.hutool.core.map.MapUtil;
|
||||||
import cn.hutool.core.util.ArrayUtil;
|
import cn.hutool.core.util.ArrayUtil;
|
||||||
import cn.hutool.core.util.ObjectUtil;
|
import cn.hutool.core.util.ObjectUtil;
|
||||||
@@ -212,39 +211,7 @@ public class LogAspect {
|
|||||||
* @return 参数日志字符串
|
* @return 参数日志字符串
|
||||||
*/
|
*/
|
||||||
private String serializeArg(Object arg, String[] exclude) {
|
private String serializeArg(Object arg, String[] exclude) {
|
||||||
if (arg instanceof Collection<?> collection) {
|
return JsonUtils.toJsonStringExcludeFields(arg, exclude);
|
||||||
List<Dict> list = new ArrayList<>(collection.size());
|
|
||||||
for (Object item : collection) {
|
|
||||||
Dict dict = toFilteredDict(item, exclude);
|
|
||||||
if (MapUtil.isNotEmpty(dict)) {
|
|
||||||
list.add(dict);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return JsonUtils.toJsonString(list);
|
|
||||||
}
|
|
||||||
String str = JsonUtils.toJsonString(arg);
|
|
||||||
Dict dict = JsonUtils.parseMap(str);
|
|
||||||
if (MapUtil.isNotEmpty(dict)) {
|
|
||||||
MapUtil.removeAny(dict, exclude);
|
|
||||||
return JsonUtils.toJsonString(dict);
|
|
||||||
}
|
|
||||||
return str;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 将参数转为已排除指定字段的字典。
|
|
||||||
*
|
|
||||||
* @param value 参数值
|
|
||||||
* @param exclude 排除字段名
|
|
||||||
* @return 已过滤字段的字典
|
|
||||||
*/
|
|
||||||
private Dict toFilteredDict(Object value, String[] exclude) {
|
|
||||||
String str = JsonUtils.toJsonString(value);
|
|
||||||
Dict dict = JsonUtils.parseMap(str);
|
|
||||||
if (MapUtil.isNotEmpty(dict)) {
|
|
||||||
MapUtil.removeAny(dict, exclude);
|
|
||||||
}
|
|
||||||
return dict;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|||||||
@@ -1,7 +1,6 @@
|
|||||||
package org.dromara.gateway.filter;
|
package org.dromara.gateway.filter;
|
||||||
|
|
||||||
import cn.hutool.core.map.MapUtil;
|
import cn.hutool.core.map.MapUtil;
|
||||||
import cn.hutool.core.util.ArrayUtil;
|
|
||||||
import cn.hutool.core.util.ObjectUtil;
|
import cn.hutool.core.util.ObjectUtil;
|
||||||
import jakarta.servlet.FilterChain;
|
import jakarta.servlet.FilterChain;
|
||||||
import jakarta.servlet.ServletException;
|
import jakarta.servlet.ServletException;
|
||||||
@@ -23,13 +22,8 @@ import org.springframework.util.MultiValueMap;
|
|||||||
import org.springframework.web.filter.OncePerRequestFilter;
|
import org.springframework.web.filter.OncePerRequestFilter;
|
||||||
import org.springframework.web.util.UriComponentsBuilder;
|
import org.springframework.web.util.UriComponentsBuilder;
|
||||||
import tools.jackson.databind.JsonNode;
|
import tools.jackson.databind.JsonNode;
|
||||||
import tools.jackson.databind.json.JsonMapper;
|
|
||||||
import tools.jackson.databind.node.ArrayNode;
|
|
||||||
import tools.jackson.databind.node.ObjectNode;
|
|
||||||
|
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.util.HashSet;
|
|
||||||
import java.util.Set;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 全局日志过滤器
|
* 全局日志过滤器
|
||||||
@@ -116,35 +110,12 @@ public class GlobalLogFilter extends OncePerRequestFilter {
|
|||||||
|
|
||||||
private String removeSensitiveFields(String jsonParam) {
|
private String removeSensitiveFields(String jsonParam) {
|
||||||
try {
|
try {
|
||||||
JsonMapper jsonMapper = JsonUtils.getJsonMapper();
|
JsonNode rootNode = JsonUtils.getJsonMapper().readTree(jsonParam);
|
||||||
JsonNode rootNode = jsonMapper.readTree(jsonParam);
|
JsonUtils.removeFields(rootNode, SystemConstants.EXCLUDE_PROPERTIES);
|
||||||
removeSensitiveFields(rootNode, SystemConstants.EXCLUDE_PROPERTIES);
|
|
||||||
return rootNode.toString();
|
return rootNode.toString();
|
||||||
} catch (Exception ex) {
|
} catch (Exception ex) {
|
||||||
return jsonParam;
|
return jsonParam;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void removeSensitiveFields(JsonNode node, String[] excludeProperties) {
|
|
||||||
if (node == null) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
if (node.isObject()) {
|
|
||||||
ObjectNode objectNode = (ObjectNode) node;
|
|
||||||
Set<String> fieldsToRemove = new HashSet<>();
|
|
||||||
objectNode.propertyNames().forEach(fieldName -> {
|
|
||||||
if (ArrayUtil.contains(excludeProperties, fieldName)) {
|
|
||||||
fieldsToRemove.add(fieldName);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
fieldsToRemove.forEach(objectNode::remove);
|
|
||||||
objectNode.values().forEach(child -> removeSensitiveFields(child, excludeProperties));
|
|
||||||
} else if (node.isArray()) {
|
|
||||||
ArrayNode arrayNode = (ArrayNode) node;
|
|
||||||
for (JsonNode child : arrayNode) {
|
|
||||||
removeSensitiveFields(child, excludeProperties);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user