AOP 获取返回值及 RequestBody 值
一开始使用 spring 拦截器请求记录日志,对于请求路径、header 这些都很好获取,唯独 POST 请求无法获取其中的 RequestBody。
原因很明显,RequestBody 是只能读取一次的,如果在拦截器中读取了,就无法通过 @RequestBody 注解去获取,因为这个数据是内存中的流数据。
这时候明显需要使用到 AOP 了
利用 AOP 读取 RequestBody
AOP 就是用来做切面的,具体概念就不说了,这里就只讲解具体问题的思路。
这里用 AOP 去切入 Controller 里面所有 public 的方法,利用 JoinPoint 获取参数,从而得到 RequestBody.
得到 RequestBody 后使用 Spring Boot 的日志打印
创建一个切面
@Aspect
@Component
public class JPushAspect {
- @Aspect 注解表明这是一个切面
- @Component 注册为组件,否则无法使用 Spring Boot 的日志
声明一个 logger
private final Logger logger = LoggerFactory.getLogger(this.getClass());
- 这里的 log 与 LogFactory 均在 org.slf4j.LoggerFactory 包下
声明切点
/** 定义切点Pointcut */
@Pointcut("@annotation(com.cutecatos.common.annotation.JPush)")
public void excudeService() {
}
编写 @AfterReturing 获取参数和返回结果
@AfterReturning(returning="rvt", pointcut="excudeService()")
public Object AfterExec(JoinPoint point, Object rvt){
Object[] args = point.getArgs();
Object o = args[0];
for (Object arg : args) {
logger.info("arg: " + arg);
}
//pointcut是对应的注解类 rvt就是方法运行完之后要返回的值
logger.info("AfterReturning增强:获取目标方法的返回值:" + rvt);
JSONObject jsonObject = JSON.parseObject(JSON.toJSONString(rvt));
int code = Integer.parseInt(jsonObject.get("code").toString());
if (code==200){
logger.info("成功");
}else{
logger.info("失败");
}
return rvt;
}
- JoinPoint.getArgs() 可以得到目标方法的参数,返回类型为 Object[]
- RequestBody 作为参数时,因为是在调用方法前已经被 Spring 读取并解析了,所以不存在重复读取的问题,调用目标方法结束时,AfterReturning 的 AOP 被执行,拿到传递给目标的参数
- 同时使用 returning 表明我们返回参数的对象,可以根据实际的业务来对该对象进行逻辑处理,例如:更新前后的记录。。
还没有评论,来说两句吧...