AOP併發情況下列印請求資訊
阿新 • • 發佈:2022-05-13
AOP列印引數在併發情況下會出現請求資訊執行緒序列的問題,經改造如下:
package com.example.aspect; import com.alibaba.fastjson2.JSON; import com.pacific.external.callback.util.CurrentContextUtils; import org.apache.commons.lang.ArrayUtils; import org.aspectj.lang.JoinPoint; import org.aspectj.lang.Signature; import org.aspectj.lang.annotation.*;import org.aspectj.lang.reflect.MethodSignature; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.stereotype.Component; import org.springframework.web.multipart.MultipartFile; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse;import java.util.Arrays; import java.util.List; import java.util.stream.Collectors; import java.util.stream.Stream; /** * ClassName HttpAspect * * @Description AOP 日誌列印 * @Author mingtian * @Date 2022/5/13 13:18 * @Version 1.0 */ @Aspect @Component public class HttpAspect { /** * 列印日誌*/ protected Logger logger = LoggerFactory.getLogger(HttpAspect.class); /** * 跨行 */ private static final String LINE_SEPARATOR = System.lineSeparator(); /** * 要處理的方法,包名+類名+方法名 */ @Pointcut("execution(* com.example.controller..*.*(..))") public void cut() { } /** * //在呼叫上面 @Pointcut標註的方法前執行以下方法 * * @param joinPoint */ @Before("cut()") public void doBefore(JoinPoint joinPoint) { logger.info("------------------------ Start ----------------------------"); HttpServletRequest request = CurrentContextUtils.getCurrentRequestInfo(); Signature signature = joinPoint.getSignature(); StringBuilder requestInfo = new StringBuilder(32); // 列印請求引數 requestInfo.append(LINE_SEPARATOR); requestInfo.append("Request MethodType:").append(request.getMethod()).append(LINE_SEPARATOR); requestInfo.append("Request IP:").append(request.getRemoteAddr()).append(LINE_SEPARATOR); requestInfo.append("Request Url:").append(request.getRequestURL().toString()).append(LINE_SEPARATOR); requestInfo.append("Request Class.Methods:").append(signature.getDeclaringTypeName()).append(".").append(signature.getName()).append(LINE_SEPARATOR); Object[] args = joinPoint.getArgs(); // 序列化時過濾掉request和response List<Object> logArgs = streamOf(args).filter(arg -> (!(arg instanceof HttpServletRequest) && !(arg instanceof HttpServletResponse))) .collect(Collectors.toList()); String argStr = JSON.toJSONString(logArgs); requestInfo.append("Request Param:").append(argStr).append(LINE_SEPARATOR); logger.info("requestInfo:{}", requestInfo); } /** * 判斷引數型別是否是檔案 * * @param signature * @return */ public boolean checkParamType(Signature signature) { MethodSignature methodSignature = (MethodSignature) signature; Class<?>[] parameterTypes = methodSignature.getParameterTypes(); logger.info("parameterTypes:{}", (Object) parameterTypes); for (Class<?> cla : parameterTypes) { if (isFile(cla)) { return true; } } return false; } /** * 過濾工具類 * * @param array * @param <T> * @return */ public static <T> Stream<T> streamOf(T[] array) { return ArrayUtils.isEmpty(array) ? Stream.empty() : Arrays.stream(array); } /** * 呼叫方法以何種方式結束,都會執行 */ @After("cut()") public void doAfter() { } /** * //在呼叫上面 @Pointcut標註的方法後執行。用於獲取返回值 * * @param obj */ @AfterReturning(returning = "obj", pointcut = "cut()") public void doAfterReturning(Object obj) { logger.info("Response Result:{}", JSON.toJSONString(obj)); logger.info("------------------------ End ----------------------------" + LINE_SEPARATOR); } /** * 檔案上傳欄位不列印 * * @param clazz * @return */ private boolean isFile(Class<?> clazz) { if (MultipartFile.class.isAssignableFrom(clazz)) { return true; } return (clazz.isArray()) && (MultipartFile.class.isAssignableFrom(clazz.getComponentType())); } }
獲取當前執行緒工具類:
package com.example.util; import org.springframework.web.context.request.RequestContextHolder; import org.springframework.web.context.request.ServletRequestAttributes; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; /** * @Description: CurrentContextUtils 獲取當前執行緒方法 * @Author: mingtian * @CreateDate: 2022/5/13 13:12 * @Version: 1.0 */ public class CurrentContextUtils { /** * 返回當前執行緒上下文request資訊 * * @return */ public static HttpServletRequest getCurrentRequestInfo() { ServletRequestAttributes servletRequestAttributes = (ServletRequestAttributes) RequestContextHolder.getRequestAttributes(); return servletRequestAttributes.getRequest(); } /** * 返回當前執行緒上下文response資訊 * * @return */ public static HttpServletResponse getCurrentResponseInfo() { ServletRequestAttributes servletRequestAttributes = (ServletRequestAttributes) RequestContextHolder.getRequestAttributes(); return servletRequestAttributes.getResponse(); } }