一、实现的效果
请求:
http://localhost:8080/regist?username=king&age=12&password=123456
Controller:
@RestController
public class UserController {
@RequestMapping("/regist")
public Apiresult userRegister(@ModelAttribute User user) {
//....
return Apiresult.success("ok");
}
//user类包含username,age,password属性,并重写了tostring方法
}
控制台
---------Path: /regist
---------ClassName: UserController
---------MethodName: userRegister
---------ParamList: {username:king,age:12,password:123456}
二、这样做的原因
1.方便调试,和前台联调可以直接看到参数
2.记录信息,方便回查。
三、实现代码
package com.kingboy.common.tools.log;
import lombok.extern.log4j.Log4j;
import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;
import org.aspectj.lang.annotation.Pointcut;
import org.aspectj.lang.reflect.MethodSignature;
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
import org.springframework.stereotype.Component;
import org.springframework.web.bind.annotation.RequestMapping;
import java.util.Objects;
import java.util.stream.Stream;
/**
* @author kingboy--KingBoyWorld@163.com
* @date 2017/11/19 下午10:10
* @desc 方法接收的参数日志.
*/
@Log4j
@Aspect
@Component
@ConditionalOnProperty(name = "king.log.enabled", havingValue = "true")
public class ParamInfoLog {
@Pointcut("execution(* com.kingboy.controller..*(..))")
public void controller() { }
@Pointcut("execution(* com.kingboy.service..*(..))")
public void service() { }
@Pointcut("execution(* com.kingboy.repository..*(..))")
public void repository() { }
@Before("controller()")
public void controller(JoinPoint point) {
MethodSignature signature = (MethodSignature) point.getSignature();
Long count = Stream.of(signature.getMethod().getDeclaredAnnotations())
.filter(annotation -> annotation.annotationType() == RequestMapping.class)
.count();
String requestPath = count >= 1 ? signature.getMethod().getAnnotation(RequestMapping.class).value()[0] : "";
String info = String.format("path:%s | %s", requestPath, getMethodInfo(point));
log.info(info);
}
@Before("service()")
public void service(JoinPoint point) {
log.info(String.format("%s", getMethodInfo(point)));
}
@Before("repository()")
public void repository(JoinPoint point) {
log.info(String.format("%s", getMethodInfo(point)));
}
private String getMethodInfo(JoinPoint point) {
String className = point.getSignature().getDeclaringType().getSimpleName();
String methodName = point.getSignature().getName();
String[] parameterNames = ((MethodSignature) point.getSignature()).getParameterNames();
StringBuilder sb = null;
if (Objects.nonNull(parameterNames)) {
sb = new StringBuilder();
for (int i = 0; i < parameterNames.length; i++) {
String value = point.getArgs()[i] != null ? point.getArgs()[i].toString() : "null";
sb.append(parameterNames[i] + ":" + value + "; ");
}
}
sb = sb == null ? new StringBuilder() : sb;
String info = String.format("class:%s | method:%s | args:%s", className, methodName, sb.toString());
return info;
}
}
更新时间 2018-09-06 00:50:25
根据项目实际情况进行了一定的优化,可以参考以下代码,日志使用的是lombok提供的注解,更换为自己的log即可
@Slf4j
@Aspect
@Component
public class ParamLogger {
@Pointcut("execution(* com.kimzing.provider.web..*(..))")
public void controller() {
}
@Pointcut("execution(* com.kimzing.provider.service..*(..))")
public void service() {
}
@Pointcut("execution(* com.kimzing.provider.mapper..*(..))")
public void repository() {
}
@Before("controller()")
public void controller(JoinPoint point) {
}
@Around("controller()")
public Object around(ProceedingJoinPoint point) throws Throwable {
String uuid = RandomUtil.uuid();
HttpServletRequest request = ((ServletRequestAttributes) RequestContextHolder.getRequestAttributes()).getRequest();
log.info("\n\t请求标识: {}\n\t请求IP: {}\n\t请求路径: {}\n\t请求方式: {}\n\t方法描述: {}\n\t请求参数: {}",
uuid, request.getRemoteAddr(), request.getRequestURL(), request.getMethod(),
getMethodInfo(point), JSONObject.toJSONString(request.getParameterMap()));
long startTime = System.currentTimeMillis();
Object[] args = point.getArgs();
Object retVal = point.proceed(args);
long endTime = System.currentTimeMillis();
log.info("\n\t请求标识: {} \n\t执行时间: {} ms \n\t返回值: {}", uuid, endTime - startTime, JSONObject.toJSONString(retVal));
return retVal;
}
@Before("service()")
public void service(JoinPoint point) {
log.info("\n\tservice method: {}", getMethodInfo(point));
}
@Before("repository()")
public void repository(JoinPoint point) {
log.info("\n\trepository method: {}", getMethodInfo(point));
}
private String getMethodInfo(JoinPoint point) {
ConcurrentHashMap<String, Object> info = new ConcurrentHashMap<>(3);
info.put("class", point.getTarget().getClass().getSimpleName());
info.put("method", point.getSignature().getName());
String[] parameterNames = ((MethodSignature) point.getSignature()).getParameterNames();
ConcurrentHashMap<String, String> args = null;
if (Objects.nonNull(parameterNames)) {
args = new ConcurrentHashMap<>(parameterNames.length);
for (int i = 0; i < parameterNames.length; i++) {
String value = point.getArgs()[i] != null ? point.getArgs()[i].toString() : "null";
args.put(parameterNames[i], value);
}
info.put("args", args);
}
return JSONObject.toJSONString(info);
}
}