Selaa lähdekoodia

refactor(logging): 优化第三方接口日志及请求数据处理

- 引入 ChargingUtil 替代 AESCryptoUtils 实现加密数据解密,保持代码一致性
- 对请求头进行简化处理,仅保留 content-type、authorization、content-length 三个关键字段
- 对 authorization 字段做部分隐藏处理,避免记录完整 token
- 对请求参数格式进行简化,单值数组转为简单字符串
- 请求体和响应体序列化时忽略 null 值,提高日志清晰度
- 日志中增加解密请求数据的调试输出
- 在解密业务代码中添加日志,输出操作员ID和解密数据起止标记
SheepHy 1 päivä sitten
vanhempi
commit
767948e893

+ 50 - 33
src/main/java/com/zsElectric/boot/charging/aspect/ThirdPartyApiLogAspect.java

@@ -1,12 +1,11 @@
 package com.zsElectric.boot.charging.aspect;
 
 import cn.hutool.core.util.StrUtil;
-import cn.hutool.json.JSONUtil;
+import com.fasterxml.jackson.annotation.JsonInclude;
 import com.fasterxml.jackson.databind.ObjectMapper;
 import com.zsElectric.boot.charging.entity.ThirdPartyApiLog;
 import com.zsElectric.boot.charging.service.ThirdPartyApiLogService;
-import com.zsElectric.boot.common.constant.ConnectivityConstants;
-import com.zsElectric.boot.common.util.AESCryptoUtils;
+import com.zsElectric.boot.common.util.electric.ChargingUtil;
 import com.zsElectric.boot.common.util.electric.RequestParmsEntity;
 import com.zsElectric.boot.common.util.electric.ResponseParmsEntity;
 import jakarta.servlet.http.HttpServletRequest;
@@ -21,9 +20,11 @@ import org.springframework.web.context.request.RequestContextHolder;
 import org.springframework.web.context.request.ServletRequestAttributes;
 
 import java.time.LocalDateTime;
-import java.util.Enumeration;
+import java.util.Arrays;
 import java.util.HashMap;
+import java.util.HashSet;
 import java.util.Map;
+import java.util.Set;
 
 /**
  * 第三方接口日志记录切面
@@ -40,6 +41,12 @@ public class ThirdPartyApiLogAspect {
 
     private final ThirdPartyApiLogService thirdPartyApiLogService;
     private final ObjectMapper objectMapper;
+    private final ChargingUtil chargingUtil;
+    
+    /** 需要保留的关键请求头 */
+    private static final Set<String> IMPORTANT_HEADERS = new HashSet<>(Arrays.asList(
+            "content-type", "authorization", "content-length"
+    ));
 
     /**
      * 定义切入点: LinkDataController 的所有方法
@@ -99,13 +106,23 @@ public class ThirdPartyApiLogAspect {
                 apiLog.setClientIp(getClientIp(request));
                 apiLog.setUserAgent(request.getHeader("User-Agent"));
                 
-                // 请求头
-                apiLog.setRequestHeaders(getRequestHeaders(request));
+                // 请求头(只保留关键信息)
+                apiLog.setRequestHeaders(getSimplifiedHeaders(request));
                 
                 // 请求参数
                 Map<String, String[]> parameterMap = request.getParameterMap();
                 if (!parameterMap.isEmpty()) {
-                    apiLog.setRequestParams(objectMapper.writeValueAsString(parameterMap));
+                    // 简化参数格式,单值的数组转为简单字符串
+                    Map<String, Object> simplifiedParams = new HashMap<>();
+                    for (Map.Entry<String, String[]> entry : parameterMap.entrySet()) {
+                        String[] values = entry.getValue();
+                        if (values != null && values.length == 1) {
+                            simplifiedParams.put(entry.getKey(), values[0]);
+                        } else {
+                            simplifiedParams.put(entry.getKey(), values);
+                        }
+                    }
+                    apiLog.setRequestParams(objectMapper.writeValueAsString(simplifiedParams));
                 }
                 
                 // 请求体(从切点参数中获取)
@@ -113,7 +130,10 @@ public class ThirdPartyApiLogAspect {
                 if (args != null && args.length > 0) {
                     for (Object arg : args) {
                         if (arg != null && !(arg instanceof HttpServletRequest) && !(arg instanceof jakarta.servlet.http.HttpServletResponse)) {
-                            apiLog.setRequestBody(objectMapper.writeValueAsString(arg));
+                            // 序列化时忽略null值
+                            ObjectMapper cleanMapper = objectMapper.copy();
+                            cleanMapper.setSerializationInclusion(JsonInclude.Include.NON_NULL);
+                            apiLog.setRequestBody(cleanMapper.writeValueAsString(arg));
                             
                             // 尝试提取业务字段
                             extractBusinessFields(arg, apiLog);
@@ -136,9 +156,12 @@ public class ThirdPartyApiLogAspect {
             apiLog.setIsSuccess(1);
             
             if (result != null) {
-                apiLog.setResponseBody(objectMapper.writeValueAsString(result));
+                // 序列化时忽略null值
+                ObjectMapper cleanMapper = objectMapper.copy();
+                cleanMapper.setSerializationInclusion(JsonInclude.Include.NON_NULL);
+                apiLog.setResponseBody(cleanMapper.writeValueAsString(result));
                 
-                // 尝试解密响应数据(针对 ResponseParmsEntity 类型)
+                // 解密响应数据(针对 ResponseParmsEntity 类型)
                 decryptResponseData(result, apiLog);
             }
             
@@ -168,19 +191,13 @@ public class ThirdPartyApiLogAspect {
      */
     private void decryptRequestData(Object requestBody, ThirdPartyApiLog apiLog) {
         try {
-            // 判断是否为 RequestParmsEntity 类型
             if (requestBody instanceof RequestParmsEntity) {
                 RequestParmsEntity requestParms = (RequestParmsEntity) requestBody;
                 String encryptedData = requestParms.getData();
                 
                 if (StrUtil.isNotBlank(encryptedData)) {
-                    // 使用系统密钥解密
-                    String decryptedData = AESCryptoUtils.decrypt(
-                        encryptedData, 
-                        ConnectivityConstants.DATA_SECRET, 
-                        ConnectivityConstants.DATA_SECRET_IV
-                    );
-                    
+                    // 使用 ChargingUtil 解密(与业务代码保持一致)
+                    String decryptedData = chargingUtil.decryptData(encryptedData);
                     apiLog.setDecryptedRequestData(decryptedData);
                     log.debug("请求数据解密成功: {}", decryptedData);
                 }
@@ -196,19 +213,13 @@ public class ThirdPartyApiLogAspect {
      */
     private void decryptResponseData(Object responseBody, ThirdPartyApiLog apiLog) {
         try {
-            // 判断是否为 ResponseParmsEntity 类型
             if (responseBody instanceof ResponseParmsEntity) {
                 ResponseParmsEntity responseParms = (ResponseParmsEntity) responseBody;
                 String encryptedData = responseParms.getData();
                 
                 if (StrUtil.isNotBlank(encryptedData)) {
-                    // 使用系统密钥解密
-                    String decryptedData = AESCryptoUtils.decrypt(
-                        encryptedData, 
-                        ConnectivityConstants.DATA_SECRET, 
-                        ConnectivityConstants.DATA_SECRET_IV
-                    );
-                    
+                    // 使用 ChargingUtil 解密(与业务代码保持一致)
+                    String decryptedData = chargingUtil.decryptData(encryptedData);
                     apiLog.setDecryptedResponseData(decryptedData);
                     log.debug("响应数据解密成功: {}", decryptedData);
                 }
@@ -268,17 +279,23 @@ public class ThirdPartyApiLogAspect {
     }
 
     /**
-     * 获取请求头信息
+     * 获取简化的请求头信息(只保留关键字段)
      */
-    private String getRequestHeaders(HttpServletRequest request) {
+    private String getSimplifiedHeaders(HttpServletRequest request) {
         try {
             Map<String, String> headers = new HashMap<>();
-            Enumeration<String> headerNames = request.getHeaderNames();
-            while (headerNames.hasMoreElements()) {
-                String headerName = headerNames.nextElement();
-                headers.put(headerName, request.getHeader(headerName));
+            for (String headerName : IMPORTANT_HEADERS) {
+                String headerValue = request.getHeader(headerName);
+                if (StrUtil.isNotBlank(headerValue)) {
+                    // 对于 authorization 只保留类型,不记录完整 token
+                    if ("authorization".equalsIgnoreCase(headerName) && headerValue.length() > 20) {
+                        headers.put(headerName, headerValue.substring(0, 20) + "...");
+                    } else {
+                        headers.put(headerName, headerValue);
+                    }
+                }
             }
-            return objectMapper.writeValueAsString(headers);
+            return headers.isEmpty() ? null : objectMapper.writeValueAsString(headers);
         } catch (Exception e) {
             log.error("获取请求头失败: {}", e.getMessage());
             return null;

+ 3 - 0
src/main/java/com/zsElectric/boot/charging/service/impl/ChargingReceptionServiceImpl.java

@@ -177,7 +177,10 @@ public class ChargingReceptionServiceImpl implements ChargingReceptionService {
             throw new BusinessException("数据验签失败");
         }
         String decryptData = chargingUtil.decryptData(requestDTO.getData());
+        log.info("==================== 解密数据开始 ====================");
+        log.info("操作员ID: {}", requestDTO.getOperatorID());
         log.info("解密后的数据:{}", decryptData);
+        log.info("==================== 解密数据结束 ====================");
         return decryptData;
     }