版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/zhangsweet1991/article/details/83859404
spring 的AOP是通过cglib动态代理和jdk的动态代理实现的。
先把我的打印日志代码贴出来
package com.zhd.exploit.api.config;
import java.util.HashMap;
import java.util.Map;
import java.util.UUID;
import javax.servlet.http.HttpServletResponseWrapper;
import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Pointcut;
import org.aspectj.lang.reflect.MethodSignature;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.core.annotation.Order;
import org.springframework.stereotype.Component;
import org.springframework.web.servlet.mvc.method.annotation.ExtendedServletRequestDataBinder;
import com.alibaba.fastjson.JSONObject;
@Aspect
@Component
@Order(1)
public class ControllerLogInterceptor {
private static final Logger log = LoggerFactory.getLogger(ControllerLogInterceptor.class);
//创建Pointcut表示式,表示所有controller请求
@Pointcut("execution(* com..*.controller..*(..))")
private void controllerAspect() {
}// 请求method前打印内容
@Around(value = "controllerAspect()")
public void around(ProceedingJoinPoint pjp) throws Throwable {
//通过uuid关联请求参数和返回参数
String uuid = UUID.randomUUID().toString().replaceAll("-", "");
methodBefore(pjp, uuid);
try {
Object proceed = pjp.proceed();
methodAfterReturing(proceed, uuid);
} catch (Exception e) {
log.error("[{}]Response异常内容:{}", uuid, e);
throw e;
}
}
public void methodBefore(JoinPoint joinPoint, String uuid) {
// 打印请求内容
try {
// 下面两个数组中,参数值和参数名的个数和位置是一一对应的。
Object[] objs = joinPoint.getArgs();
String[] argNames = ((MethodSignature) joinPoint.getSignature()).getParameterNames(); // 参数名
Map<String, Object> paramMap = new HashMap<String, Object>();
for (int i = 0; i < objs.length; i++) {
if (!(objs[i] instanceof ExtendedServletRequestDataBinder) && !(objs[i] instanceof HttpServletResponseWrapper)) {
paramMap.put(argNames[i], objs[i]);
}
}
if (paramMap.size() > 0) {
log.info("\n[{}]方法:{}\n参数:{}", uuid, joinPoint.getSignature(), JSONObject.toJSONString(paramMap));
}
} catch (Exception e) {
log.error("[{}]AOP methodBefore:", uuid, e);
}
}
public void methodAfterReturing(Object o, String uuid) {
try {
if (o != null)
log.info("[{}]Response内容:{}", uuid, JSONObject.toJSON(o));
} catch (Exception e) {
log.error("[{}]AOP methodAfterReturing:", uuid, e);
}
}
}
测试
请求参数类型1
@RequestMapping(value = "/test0", method = RequestMethod.GET, produces = { MediaType.APPLICATION_JSON_VALUE })
public Result test0(@RequestParam String name, @RequestParam String password) {
System.out.println("test0 OK");
return new Result("1", "mock a Result");
}
打印日志:
[fe7155a3089b4dd7896b759a933cf958]方法:Result com.zhd.exploit.api.controller.TestController.test0(String,String)
参数:{"password":"123","name":"zhang"}
请求参数类型2
@RequestMapping(value = "/test1", method = RequestMethod.GET, produces = { MediaType.APPLICATION_JSON_VALUE })
public Result test1(PayDTO payDTO) {
System.out.println("test1 OK");
return new Result("1", "mock a Result");
}
打印日志:
[a2f7d19dea834c54a45b480bd4e8c3cd]方法:Result com.zhd.exploit.api.controller.TestController.test1(PayDTO)
参数:{"payDTO":{"appmount":"10","paytype":"1"}}
请求参数类型3
@RequestMapping(value = "/test2", method = RequestMethod.POST, produces = { MediaType.APPLICATION_JSON_VALUE })
public Result test2(@RequestBody PayDTO payDTO) {
System.out.println("test2 OK");
return new Result("2", "mock a Result");
}
打印日志:
[cd6a3d9d05244eee95bbf3c607d038cc]方法:Result com.zhd.exploit.api.controller.TestController.test2(PayDTO)
参数:{"payDTO":{"appmount":"10","paytype":"1"}}