From 152781b05131e48bf6e94d71cc72dd54af52a3fb Mon Sep 17 00:00:00 2001
From: houzhongjian <houzhongyi@126.com>
Date: 星期四, 10 四月 2025 14:13:29 +0800
Subject: [PATCH] 恢复iailab-framework

---
 iailab-framework/iailab-common-web/src/main/java/com/iailab/framework/apilog/core/interceptor/ApiAccessLogInterceptor.java |  103 +++++++++++++++++++++++++++++++++++++++++++++++++++
 1 files changed, 103 insertions(+), 0 deletions(-)

diff --git a/iailab-framework/iailab-common-web/src/main/java/com/iailab/framework/apilog/core/interceptor/ApiAccessLogInterceptor.java b/iailab-framework/iailab-common-web/src/main/java/com/iailab/framework/apilog/core/interceptor/ApiAccessLogInterceptor.java
new file mode 100644
index 0000000..f22500a
--- /dev/null
+++ b/iailab-framework/iailab-common-web/src/main/java/com/iailab/framework/apilog/core/interceptor/ApiAccessLogInterceptor.java
@@ -0,0 +1,103 @@
+package com.iailab.framework.apilog.core.interceptor;
+
+import cn.hutool.core.collection.CollUtil;
+import cn.hutool.core.io.FileUtil;
+import cn.hutool.core.io.resource.ResourceUtil;
+import cn.hutool.core.util.StrUtil;
+import com.iailab.framework.common.util.servlet.ServletUtils;
+import com.iailab.framework.common.util.spring.SpringUtils;
+import lombok.extern.slf4j.Slf4j;
+import org.springframework.util.StopWatch;
+import org.springframework.web.method.HandlerMethod;
+import org.springframework.web.servlet.HandlerInterceptor;
+
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+import java.lang.reflect.Method;
+import java.util.List;
+import java.util.Map;
+import java.util.Optional;
+import java.util.stream.IntStream;
+
+/**
+ * API 访问日志 Interceptor
+ *
+ * 目的:在非 prod 环境时,打印 request 和 response 两条日志到日志文件(控制台)中。
+ *
+ * @author iailab
+ */
+@Slf4j
+public class ApiAccessLogInterceptor implements HandlerInterceptor {
+
+    public static final String ATTRIBUTE_HANDLER_METHOD = "HANDLER_METHOD";
+
+    private static final String ATTRIBUTE_STOP_WATCH = "ApiAccessLogInterceptor.StopWatch";
+
+    @Override
+    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) {
+        // 记录 HandlerMethod,提供给 ApiAccessLogFilter 使用
+        HandlerMethod handlerMethod = handler instanceof HandlerMethod ? (HandlerMethod) handler : null;
+        if (handlerMethod != null) {
+            request.setAttribute(ATTRIBUTE_HANDLER_METHOD, handlerMethod);
+        }
+
+        // 打印 request 日志
+        if (!SpringUtils.isProd()) {
+            Map<String, String> queryString = ServletUtils.getParamMap(request);
+            String requestBody = ServletUtils.isJsonRequest(request) ? ServletUtils.getBody(request) : null;
+            if (CollUtil.isEmpty(queryString) && StrUtil.isEmpty(requestBody)) {
+                log.info("[preHandle][开始请求 URL({}) 无参数]", request.getRequestURI());
+            } else {
+                log.info("[preHandle][开始请求 URL({}) 参数({})]", request.getRequestURI(),
+                        StrUtil.blankToDefault(requestBody, queryString.toString()));
+            }
+            // 计时
+            StopWatch stopWatch = new StopWatch();
+            stopWatch.start();
+            request.setAttribute(ATTRIBUTE_STOP_WATCH, stopWatch);
+            // 打印 Controller 路径
+            printHandlerMethodPosition(handlerMethod);
+        }
+        return true;
+    }
+
+    @Override
+    public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) {
+        // 打印 response 日志
+        if (!SpringUtils.isProd()) {
+            StopWatch stopWatch = (StopWatch) request.getAttribute(ATTRIBUTE_STOP_WATCH);
+            stopWatch.stop();
+            log.info("[afterCompletion][完成请求 URL({}) 耗时({} ms)]",
+                    request.getRequestURI(), stopWatch.getTotalTimeMillis());
+        }
+    }
+
+    /**
+     * 打印 Controller 方法路径
+     */
+    private void printHandlerMethodPosition(HandlerMethod handlerMethod) {
+        if (handlerMethod == null) {
+            return;
+        }
+        Method method = handlerMethod.getMethod();
+        Class<?> clazz = method.getDeclaringClass();
+        try {
+            // 获取 method 的 lineNumber
+            List<String> clazzContents = FileUtil.readUtf8Lines(
+                    ResourceUtil.getResource(null, clazz).getPath().replace("/target/classes/", "/src/main/java/")
+                            + clazz.getSimpleName() + ".java");
+            Optional<Integer> lineNumber = IntStream.range(0, clazzContents.size())
+                    .filter(i -> clazzContents.get(i).contains(" " + method.getName() + "(")) // 简单匹配,不考虑方法重名
+                    .mapToObj(i -> i + 1) // 行号从 1 开始
+                    .findFirst();
+            if (!lineNumber.isPresent()) {
+                return;
+            }
+            // 打印结果
+            System.out.printf("\tController 方法路径:%s(%s.java:%d)\n", clazz.getName(), clazz.getSimpleName(), lineNumber.get());
+        } catch (Exception ignore) {
+            // 忽略异常。原因:仅仅打印,非重要逻辑
+        }
+    }
+
+}

--
Gitblit v1.9.3