From 81cdf5b3c7314e23bf0e11e0eecd3cf9d181e395 Mon Sep 17 00:00:00 2001 From: lizhixian <1317094543@qq.com> Date: Wed, 27 Mar 2024 16:31:04 +0800 Subject: [PATCH] =?UTF-8?q?fix:=E8=A7=A3=E5=86=B3PlusWebInvokeTimeIntercep?= =?UTF-8?q?tor=E8=8E=B7=E5=8F=96=E7=9C=9F=E5=AE=9E=E8=AF=B7=E6=B1=82?= =?UTF-8?q?=E8=B7=AF=E5=BE=84=E5=92=8C=E5=8F=82=E6=95=B0=E4=B8=8D=E5=87=86?= =?UTF-8?q?=E7=A1=AE=E9=97=AE=E9=A2=98?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../PlusWebInvokeTimeInterceptor.java | 154 ++++++++++++++---- 1 file changed, 125 insertions(+), 29 deletions(-) diff --git a/ruoyi-common/ruoyi-common-web/src/main/java/org/dromara/common/web/interceptor/PlusWebInvokeTimeInterceptor.java b/ruoyi-common/ruoyi-common-web/src/main/java/org/dromara/common/web/interceptor/PlusWebInvokeTimeInterceptor.java index 12c808647..c91dd1ebf 100644 --- a/ruoyi-common/ruoyi-common-web/src/main/java/org/dromara/common/web/interceptor/PlusWebInvokeTimeInterceptor.java +++ b/ruoyi-common/ruoyi-common-web/src/main/java/org/dromara/common/web/interceptor/PlusWebInvokeTimeInterceptor.java @@ -1,20 +1,27 @@ package org.dromara.common.web.interceptor; -import cn.hutool.core.io.IoUtil; -import cn.hutool.core.map.MapUtil; +import com.alibaba.ttl.TransmittableThreadLocal; import jakarta.servlet.http.HttpServletRequest; import jakarta.servlet.http.HttpServletResponse; import lombok.extern.slf4j.Slf4j; +import org.apache.commons.lang3.ObjectUtils; import org.apache.commons.lang3.time.StopWatch; import org.dromara.common.core.utils.SpringUtils; import org.dromara.common.core.utils.StringUtils; import org.dromara.common.json.utils.JsonUtils; -import org.dromara.common.web.filter.RepeatedlyRequestWrapper; +import org.springframework.core.annotation.AnnotatedElementUtils; import org.springframework.http.MediaType; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.method.HandlerMethod; import org.springframework.web.servlet.HandlerInterceptor; import org.springframework.web.servlet.ModelAndView; import java.io.BufferedReader; +import java.io.IOException; +import java.lang.reflect.Method; +import java.util.Collections; +import java.util.Enumeration; +import java.util.LinkedHashMap; import java.util.Map; /** @@ -29,34 +36,20 @@ public class PlusWebInvokeTimeInterceptor implements HandlerInterceptor { private final String prodProfile = "prod"; - private final static ThreadLocal KEY_CACHE = new ThreadLocal<>(); + private final TransmittableThreadLocal invokeTimeTL = new TransmittableThreadLocal<>(); @Override public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception { if (!prodProfile.equals(SpringUtils.getActiveProfile())) { - String url = request.getMethod() + " " + request.getRequestURI(); - - // 打印请求参数 - if (isJsonRequest(request)) { - String jsonParam = ""; - if (request instanceof RepeatedlyRequestWrapper) { - BufferedReader reader = request.getReader(); - jsonParam = IoUtil.read(reader); - } - log.info("[PLUS]开始请求 => URL[{}],参数类型[json],参数:[{}]", url, jsonParam); - } else { - Map parameterMap = request.getParameterMap(); - if (MapUtil.isNotEmpty(parameterMap)) { - String parameters = JsonUtils.toJsonString(parameterMap); - log.info("[PLUS]开始请求 => URL[{}],参数类型[param],参数:[{}]", url, parameters); - } else { - log.info("[PLUS]开始请求 => URL[{}],无参数", url); - } + if (handler instanceof HandlerMethod handlerMethod) { + String apiUrl = getRequestUrl(handlerMethod); + log.info("[PLUS]开始请求 => URL[{}]", request.getMethod() + " " + apiUrl); + parameterMap(request); + parameterBodyMap(request, apiUrl); + StopWatch stopWatch = new StopWatch(); + invokeTimeTL.set(stopWatch); + stopWatch.start(); } - - StopWatch stopWatch = new StopWatch(); - KEY_CACHE.set(stopWatch); - stopWatch.start(); } return true; } @@ -69,10 +62,14 @@ public class PlusWebInvokeTimeInterceptor implements HandlerInterceptor { @Override public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception { if (!prodProfile.equals(SpringUtils.getActiveProfile())) { - StopWatch stopWatch = KEY_CACHE.get(); + StopWatch stopWatch = invokeTimeTL.get(); stopWatch.stop(); - log.info("[PLUS]结束请求 => URL[{}],耗时:[{}]毫秒", request.getMethod() + " " + request.getRequestURI(), stopWatch.getTime()); - KEY_CACHE.remove(); + if (handler instanceof HandlerMethod handlerMethod) { + String apiUrl = getRequestUrl(handlerMethod); + log.info("[PLUS]结束请求 => URL[{}],耗时:[{}]毫秒", request.getMethod() + " " + apiUrl, stopWatch.getTime()); + + } + invokeTimeTL.remove(); } } @@ -81,7 +78,9 @@ public class PlusWebInvokeTimeInterceptor implements HandlerInterceptor { * * @param request request * @return boolean + * @since 5.0.0 */ + @Deprecated private boolean isJsonRequest(HttpServletRequest request) { String contentType = request.getContentType(); if (contentType != null) { @@ -90,4 +89,101 @@ public class PlusWebInvokeTimeInterceptor implements HandlerInterceptor { return false; } + /** + * 获取请求的真实接口地址 + * + * @param handlerMethod handlerMethod + * @return 返回接口地址 + */ + private static String getRequestUrl(HandlerMethod handlerMethod) { + StringBuilder apiURL = new StringBuilder(); + //获取类上的RequestMapping注解 + RequestMapping mapping = handlerMethod.getBeanType().getAnnotation(RequestMapping.class); + if (null != mapping) { + apiURL.append(mapping.value()[0]); + } + Method method = handlerMethod.getMethod(); + //获取方法上的RequestMapping注解 + RequestMapping methodRequestMapping = AnnotatedElementUtils.findMergedAnnotation(method, RequestMapping.class); + if (methodRequestMapping != null) { + String[] value = methodRequestMapping.value(); + if (value.length > 0) { + apiURL.append(value[0]); + } + } + return apiURL.toString(); + } + + /** + * 获取GET请求中,使用entity中的参数 + * + * @param request request + */ + private void parameterMap(HttpServletRequest request) { + Enumeration parameterNames = request.getParameterNames(); + Map getParameters = new LinkedHashMap<>(); + if (parameterNames.hasMoreElements()) { + while (parameterNames.hasMoreElements()) { + String name = parameterNames.nextElement(); + String value = request.getParameter(name); + getParameters.put(name, value); + } + log.info("[PLUS]请求参数 => 参数内容:[{}]", JsonUtils.toJsonString(getParameters)); + } + } + + /** + * 获取restful风格参数和body请求参数 + * + * @param request 请求 + * @param apiURL 接口地址 + */ + private static void parameterBodyMap(HttpServletRequest request, String apiURL) { + //获取restful风格参数 + Map parameterMap = findCommonCharacters(request.getRequestURI(), apiURL); + if (ObjectUtils.isNotEmpty(parameterMap)) { + log.info("[PLUS]请求参数 => 参数内容:[{}]", JsonUtils.toJsonString(parameterMap)); + } + //获取body参数 + int contentLength = request.getContentLength(); + if (contentLength > 0) { + try { + // 获取请求体的输入流 + BufferedReader reader = request.getReader(); + StringBuilder body = new StringBuilder(); + String line; + // 逐行读取请求体内容 + while ((line = reader.readLine()) != null) { + body.append(line); + } + if (ObjectUtils.isNotEmpty(body)) { + log.info("[PLUS]请求参数 => 参数内容:[{}]", body); + } + } catch (IOException e) { + log.error("[PLUS]拦截器获取body参数异常", e); + } + } + } + + /** + * 获取restfull风格参数 + * + * @param str1 全路径 + * @param str2 接口路径 + * @return Map + */ + private static Map findCommonCharacters(String str1, String str2) { + if (str1 == null || str2 == null) { + return Collections.emptyMap(); + } + int index = StringUtils.indexOfDifference(str1, str2); + if (index == -1) { + return Collections.emptyMap(); + } + String values = StringUtils.substring(str1, index); + String params = StringUtils.substring(str2, index); + Map parameterMap = new LinkedHashMap<>(); + parameterMap.put(params.replace("{","").replace("}",""), values); + return parameterMap; + } }