通过spring AOP记录接口请求参数日志,方便并节省代码,只需要在一个类中写记录代码,就可应用的所有请求接口中。
首先,添加包
<dependency>
<groupId>org.aspectj</groupId>
<artifactId>aspectjweaver</artifactId>
<version>1.8.13</version>
</dependency>
创建类AopHandler,请求参数是健值对的记录方法
@Aspect
@Component
@Slf4j
public class AopHandler {
@Around("@annotation(requestMapping)")
public Object recordCallLog(ProceedingJoinPoint pjp, RequestMapping requestMapping) throws Throwable {
long start = System.currentTimeMillis();
Signature signature = pjp.getSignature();
String clazz = signature.getDeclaringTypeName();
String method = signature.getName();
Object[] parameterValues = pjp.getArgs();
StringBuilder builder = new StringBuilder();
MethodSignature methodSignature = (MethodSignature) signature;
String[] parameterNamess = methodSignature.getParameterNames();
for (int i = 0; i < parameterNamess.length; i++) {
if (i == 0) {
builder.append("?");
}
builder.append(parameterNamess[i] + "=" + parameterValues[i].toString());
if (i < parameterNamess.length - 1) {
builder.append("&");
}
}
HttpServletRequest request = ((ServletRequestAttributes) RequestContextHolder.getRequestAttributes()).getRequest();
String path = request.getRequestURL().toString();
log.info(">>>>>>:" + path + builder.toString());
Object result = pjp.proceed();
long usedTime = System.currentTimeMillis() - start;
log.info("<<<<<<:" + method + "|耗时:" + usedTime + "毫秒");
return result;
}
}
若请求参数是对象的,如
@RequestMapping("/test")
public String test(@RequestBody MqMsg msg){
return "ok";
}
则aop的参数日志记录方法为:
@Aspect
@Component
@Slf4j
public class AopHandler {
@Around("@annotation(requestMapping)")
public Object recordCallLog(ProceedingJoinPoint pjp, RequestMapping requestMapping) throws Throwable {
long start = System.currentTimeMillis();
String params = "";//多个参数时出错 JsonUtil.toJson(pjp.getArgs());
Object[] args = pjp.getArgs();
Object[] arguments = new Object[args.length];
for (int i = 0; i < args.length; i++) {
if (args[i] instanceof ServletRequest || args[i] instanceof ServletResponse || args[i] instanceof MultipartFile) {
//ServletRequest不能序列化,从入参里排除,否则报异常:java.lang.IllegalStateException: It is illegal to call this method if the current request is not in asynchronous mode (i.e. isAsyncStarted() returns false)
//ServletResponse不能序列化 从入参里排除,否则报异常:java.lang.IllegalStateException: getOutputStream() has already been called for this response
continue;
}
arguments[i] = args[i];
}
if (arguments != null) {
try {
params = JsonUtil.toJson(arguments);
} catch (Exception e) {
params = arguments.toString();
}
}
Signature signature = pjp.getSignature();
String method = signature.getName();
HttpServletRequest request = ((ServletRequestAttributes) RequestContextHolder.getRequestAttributes()).getRequest();
String path = request.getRequestURL().toString();
log.info(">>>>>>:" + path + params);
Object result = pjp.proceed();
String json = "";
if(null!=result){
json = JsonUtil.toJson(result);
}
long usedTime = System.currentTimeMillis() - start;
//log.info("<<<<<<:" + method + "|耗时:" + usedTime + "毫秒");
log.info("<<<<<< 结束请求:" + path + "|耗时:" + usedTime + "毫秒|响应:" + json );
return result;
}
}