切面Controller出入参日志打印
切面出入参日志打印
import cn.hutool.core.lang.UUID;
import cn.hutool.json.JSONUtil;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.Signature;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Pointcut;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.slf4j.MDC;
import org.springframework.stereotype.Component;
import org.springframework.web.context.request.RequestAttributes;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;
import javax.servlet.http.HttpServletRequest;
@Aspect
@Component
public class LogAspect {
private static final Logger log = LoggerFactory.getLogger(LogAspect.class);
/**
* 会话ID
*/
private final static String SESSION_TOKEN_KEY = "sessionTokenId";
/**
* 以 controller 包下定义的所有请求为切入点
*/
@Pointcut("execution(public * com.example.demo.controller..*.*(..))")
public void webLog() {
}
/**
* 环绕
*
* @param proceedingJoinPoint 切入点
* @return
* @throws Throwable
*/
@Around("webLog()")
public Object doAround(ProceedingJoinPoint proceedingJoinPoint) throws Throwable {
long startTime = System.currentTimeMillis();
MDC.put(SESSION_TOKEN_KEY, UUID.randomUUID().toString(true));
log.info("=========== 请求开始 ==========");
RequestAttributes ra = RequestContextHolder.getRequestAttributes();
ServletRequestAttributes sra = (ServletRequestAttributes) ra;
// 断言
assert sra != null;
HttpServletRequest request = sra.getRequest();
;
// 获取请求相关信息
String url = request.getRequestURL().toString();
String method = request.getMethod();
String uri = request.getRequestURI();
String queryString = request.getQueryString();
// 获取调用方法相信
Signature signature = proceedingJoinPoint.getSignature();
String className = signature.getDeclaringTypeName();
String methodName = signature.getName();
Object[] args = proceedingJoinPoint.getArgs();
// 参数
String params = "";
//获取请求参数集合并进行遍历拼接
if (args.length > 0) {
if ("POST".equals(method)) {
Object object = args[0];
params = JSONUtil.toJsonStr(object);
} else if ("GET".equals(method)) {
params = queryString;
}
}
//这里定义log输出的内容,前面是内容格式,{}按照顺序被替换为后面参数的具体值
log.info("Request => ClassMethod: {}#{}() URI: {}, method: {}, URL: {}, params: {}",
className, methodName, uri, method, url, params);
//result的值就是被拦截方法的返回值
try {
//proceed方法是调用实际所拦截的controller中的方法,这里的result为调用方法后的返回值
Object result = proceedingJoinPoint.proceed();
long endTime = System.currentTimeMillis();
//定义请求结束时的返回数据,包括调用时间、返回值结果等
log.info("Response => ClassMethod: {}#{}(), URI: {}, HttpMethod: {}, URL: {}, time: {}ms, result: {} ",
className, methodName, uri, method, url, (endTime - startTime), JSONUtil.toJsonStr(result));
return result;
} catch (Exception e) {
long endTime = System.currentTimeMillis();
log.error("Error => ClassMethod: {}#{}(), URI: {}, HttpMethod: {}, URL: {}, time: {}ms",
className, methodName, uri, method, url, (endTime - startTime), e);
throw e;
} finally {
MDC.remove(SESSION_TOKEN_KEY);
log.info("=========== 请求结束 ==========");
}
}
}
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 无需6万激活码!GitHub神秘组织3小时极速复刻Manus,手把手教你使用OpenManus搭建本
· C#/.NET/.NET Core优秀项目和框架2025年2月简报
· 葡萄城 AI 搜索升级:DeepSeek 加持,客户体验更智能
· 什么是nginx的强缓存和协商缓存
· 一文读懂知识蒸馏