From 9b4433fddf5b401edb0aace8a404ac733b122702 Mon Sep 17 00:00:00 2001
From: 田源 <tianyuan@vci-tech.com>
Date: 星期四, 03 四月 2025 14:35:02 +0800
Subject: [PATCH] 添加非密字段显示
---
Source/BladeX-Tool/blade-starter-log/src/main/java/org/springblade/core/log/aspect/RequestLogAspect.java | 260 ++++++++++++++++++++++++++++++++++++++++++++++++++++
1 files changed, 260 insertions(+), 0 deletions(-)
diff --git a/Source/BladeX-Tool/blade-starter-log/src/main/java/org/springblade/core/log/aspect/RequestLogAspect.java b/Source/BladeX-Tool/blade-starter-log/src/main/java/org/springblade/core/log/aspect/RequestLogAspect.java
new file mode 100644
index 0000000..1008b09
--- /dev/null
+++ b/Source/BladeX-Tool/blade-starter-log/src/main/java/org/springblade/core/log/aspect/RequestLogAspect.java
@@ -0,0 +1,260 @@
+/*
+ * Copyright (c) 2018-2028, DreamLu All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * Redistributions of source code must retain the above copyright notice,
+ * this list of conditions and the following disclaimer.
+ * Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * Neither the name of the dreamlu.net developer nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ * Author: DreamLu 鍗㈡槬姊� (596392912@qq.com)
+ */
+package org.springblade.core.log.aspect;
+
+import lombok.AllArgsConstructor;
+import lombok.extern.slf4j.Slf4j;
+import org.aspectj.lang.ProceedingJoinPoint;
+import org.aspectj.lang.annotation.Around;
+import org.aspectj.lang.annotation.Aspect;
+import org.aspectj.lang.reflect.MethodSignature;
+import org.springblade.core.launch.log.BladeLogLevel;
+import org.springblade.core.log.props.BladeRequestLogProperties;
+import org.springblade.core.tool.jackson.JsonUtil;
+import org.springblade.core.tool.utils.ClassUtil;
+import org.springblade.core.tool.utils.StringPool;
+import org.springblade.core.tool.utils.StringUtil;
+import org.springblade.core.tool.utils.WebUtil;
+import org.springframework.boot.autoconfigure.AutoConfiguration;
+import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
+import org.springframework.boot.autoconfigure.condition.ConditionalOnWebApplication;
+import org.springframework.core.MethodParameter;
+import org.springframework.core.io.InputStreamSource;
+import org.springframework.web.bind.annotation.PathVariable;
+import org.springframework.web.bind.annotation.RequestBody;
+import org.springframework.web.bind.annotation.RequestParam;
+import org.springframework.web.context.request.WebRequest;
+import org.springframework.web.multipart.MultipartFile;
+
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+import java.io.InputStream;
+import java.lang.reflect.Method;
+import java.util.*;
+import java.util.concurrent.TimeUnit;
+import java.util.concurrent.atomic.AtomicBoolean;
+
+/**
+ * Spring boot 鎺у埗鍣� 璇锋眰鏃ュ織锛屾柟渚夸唬鐮佽皟璇�
+ *
+ * @author L.cm
+ */
+@Slf4j
+@Aspect
+@AutoConfiguration
+@AllArgsConstructor
+@ConditionalOnWebApplication(type = ConditionalOnWebApplication.Type.SERVLET)
+@ConditionalOnProperty(value = BladeLogLevel.REQ_LOG_PROPS_PREFIX + ".enabled", havingValue = "true", matchIfMissing = true)
+public class RequestLogAspect {
+
+ private final BladeRequestLogProperties properties;
+
+ /**
+ * AOP 鐜垏 鎺у埗鍣� R 杩斿洖鍊�
+ *
+ * @param point JoinPoint
+ * @return Object
+ * @throws Throwable 寮傚父
+ */
+ @Around(
+ "execution(!static org.springblade.core.tool.api.R *(..)) && " +
+ "(@within(org.springframework.stereotype.Controller) || " +
+ "@within(org.springframework.web.bind.annotation.RestController))"
+ )
+ public Object aroundApi(ProceedingJoinPoint point) throws Throwable {
+ BladeLogLevel level = properties.getLevel();
+ // 涓嶆墦鍗版棩蹇楋紝鐩存帴杩斿洖
+ if (BladeLogLevel.NONE == level) {
+ return point.proceed();
+ }
+ HttpServletRequest request = WebUtil.getRequest();
+ String requestUrl = Objects.requireNonNull(request).getRequestURI();
+ String requestMethod = request.getMethod();
+
+ // 鏋勫缓鎴愪竴鏉¢暱 鏃ュ織锛岄伩鍏嶅苟鍙戜笅鏃ュ織閿欎贡
+ StringBuilder beforeReqLog = new StringBuilder(300);
+ // 鏃ュ織鍙傛暟
+ List<Object> beforeReqArgs = new ArrayList<>();
+ beforeReqLog.append("\n\n================ Request Start ================\n");
+ // 鎵撳嵃璺敱
+ beforeReqLog.append("===> {}: {}");
+ beforeReqArgs.add(requestMethod);
+ beforeReqArgs.add(requestUrl);
+ // 鎵撳嵃璇锋眰鍙傛暟
+ logIngArgs(point, beforeReqLog, beforeReqArgs);
+ // 鎵撳嵃璇锋眰 headers
+ logIngHeaders(request, level, beforeReqLog, beforeReqArgs);
+ beforeReqLog.append("================ Request End ================\n");
+
+ // 鎵撳嵃鎵ц鏃堕棿
+ long startNs = System.nanoTime();
+ log.info(beforeReqLog.toString(), beforeReqArgs.toArray());
+ // aop 鎵ц鍚庣殑鏃ュ織
+ StringBuilder afterReqLog = new StringBuilder(200);
+ // 鏃ュ織鍙傛暟
+ List<Object> afterReqArgs = new ArrayList<>();
+ afterReqLog.append("\n\n=============== Response Start ================\n");
+ try {
+ Object result = point.proceed();
+ // 鎵撳嵃杩斿洖缁撴瀯浣�
+ if (BladeLogLevel.BODY.lte(level)) {
+ afterReqLog.append("===Result=== {}\n");
+ afterReqArgs.add(JsonUtil.toJson(result));
+ }
+ return result;
+ } finally {
+ long tookMs = TimeUnit.NANOSECONDS.toMillis(System.nanoTime() - startNs);
+ afterReqLog.append("<=== {}: {} ({} ms)\n");
+ afterReqArgs.add(requestMethod);
+ afterReqArgs.add(requestUrl);
+ afterReqArgs.add(tookMs);
+ afterReqLog.append("=============== Response End ================\n");
+ log.info(afterReqLog.toString(), afterReqArgs.toArray());
+ }
+ }
+
+ /**
+ * 婵�鍔辫姹傚弬鏁�
+ *
+ * @param point ProceedingJoinPoint
+ * @param beforeReqLog StringBuilder
+ * @param beforeReqArgs beforeReqArgs
+ */
+ public void logIngArgs(ProceedingJoinPoint point, StringBuilder beforeReqLog, List<Object> beforeReqArgs) {
+ MethodSignature ms = (MethodSignature) point.getSignature();
+ Method method = ms.getMethod();
+ Object[] args = point.getArgs();
+ // 璇锋眰鍙傛暟澶勭悊
+ final Map<String, Object> paraMap = new HashMap<>(16);
+ // 涓�娆¤姹傚彧鑳芥湁涓�涓� request body
+ Object requestBodyValue = null;
+ for (int i = 0; i < args.length; i++) {
+ // 璇诲彇鏂规硶鍙傛暟
+ MethodParameter methodParam = ClassUtil.getMethodParameter(method, i);
+ // PathVariable 鍙傛暟璺宠繃
+ PathVariable pathVariable = methodParam.getParameterAnnotation(PathVariable.class);
+ if (pathVariable != null) {
+ continue;
+ }
+ RequestBody requestBody = methodParam.getParameterAnnotation(RequestBody.class);
+ String parameterName = methodParam.getParameterName();
+ Object value = args[i];
+ // 濡傛灉鏄痓ody鐨刯son鍒欐槸瀵硅薄
+ if (requestBody != null) {
+ requestBodyValue = value;
+ continue;
+ }
+ // 澶勭悊 鍙傛暟
+ if (value instanceof HttpServletRequest) {
+ paraMap.putAll(((HttpServletRequest) value).getParameterMap());
+ continue;
+ } else if (value instanceof WebRequest) {
+ paraMap.putAll(((WebRequest) value).getParameterMap());
+ continue;
+ } else if (value instanceof HttpServletResponse) {
+ continue;
+ } else if (value instanceof MultipartFile) {
+ MultipartFile multipartFile = (MultipartFile) value;
+ String name = multipartFile.getName();
+ String fileName = multipartFile.getOriginalFilename();
+ paraMap.put(name, fileName);
+ continue;
+ } else if (value instanceof MultipartFile[]) {
+ MultipartFile[] arr = (MultipartFile[]) value;
+ if (arr.length == 0) {
+ continue;
+ }
+ String name = arr[0].getName();
+ StringBuilder sb = new StringBuilder(arr.length);
+ for (MultipartFile multipartFile : arr) {
+ sb.append(multipartFile.getOriginalFilename());
+ sb.append(StringPool.COMMA);
+ }
+ paraMap.put(name, StringUtil.removeSuffix(sb.toString(), StringPool.COMMA));
+ continue;
+ } else if (value instanceof List) {
+ List<?> list = (List<?>) value;
+ AtomicBoolean isSkip = new AtomicBoolean(false);
+ for (Object o : list) {
+ if ("StandardMultipartFile".equalsIgnoreCase(o.getClass().getSimpleName())) {
+ isSkip.set(true);
+ break;
+ }
+ }
+ if (isSkip.get()) {
+ paraMap.put(parameterName, "姝ゅ弬鏁颁笉鑳藉簭鍒楀寲涓簀son");
+ continue;
+ }
+ }
+ // 鍙傛暟鍚�
+ RequestParam requestParam = methodParam.getParameterAnnotation(RequestParam.class);
+ String paraName = parameterName;
+ if (requestParam != null && StringUtil.isNotBlank(requestParam.value())) {
+ paraName = requestParam.value();
+ }
+ if (value == null) {
+ paraMap.put(paraName, null);
+ } else if (ClassUtil.isPrimitiveOrWrapper(value.getClass())) {
+ paraMap.put(paraName, value);
+ } else if (value instanceof InputStream) {
+ paraMap.put(paraName, "InputStream");
+ } else if (value instanceof InputStreamSource) {
+ paraMap.put(paraName, "InputStreamSource");
+ } else if (JsonUtil.canSerialize(value)) {
+ // 鍒ゆ柇妯″瀷鑳借 json 搴忓垪鍖栵紝鍒欐坊鍔�
+ paraMap.put(paraName, value);
+ } else {
+ paraMap.put(paraName, "姝ゅ弬鏁颁笉鑳藉簭鍒楀寲涓簀son");
+ }
+ }
+ // 璇锋眰鍙傛暟
+ if (paraMap.isEmpty()) {
+ beforeReqLog.append("\n");
+ } else {
+ beforeReqLog.append(" Parameters: {}\n");
+ beforeReqArgs.add(JsonUtil.toJson(paraMap));
+ }
+ if (requestBodyValue != null) {
+ beforeReqLog.append("====Body===== {}\n");
+ beforeReqArgs.add(JsonUtil.toJson(requestBodyValue));
+ }
+ }
+
+ /**
+ * 璁板綍璇锋眰澶�
+ *
+ * @param request HttpServletRequest
+ * @param level 鏃ュ織绾у埆
+ * @param beforeReqLog StringBuilder
+ * @param beforeReqArgs beforeReqArgs
+ */
+ public void logIngHeaders(HttpServletRequest request, BladeLogLevel level,
+ StringBuilder beforeReqLog, List<Object> beforeReqArgs) {
+ // 鎵撳嵃璇锋眰澶�
+ if (BladeLogLevel.HEADERS.lte(level)) {
+ Enumeration<String> headers = request.getHeaderNames();
+ while (headers.hasMoreElements()) {
+ String headerName = headers.nextElement();
+ String headerValue = request.getHeader(headerName);
+ beforeReqLog.append("===Headers=== {}: {}\n");
+ beforeReqArgs.add(headerName);
+ beforeReqArgs.add(headerValue);
+ }
+ }
+ }
+
+}
--
Gitblit v1.10.0