AOP 获取返回值及 RequestBody 值

不念不忘少年蓝@ 2024-03-26 23:19 158阅读 0赞

一开始使用 spring 拦截器请求记录日志,对于请求路径、header 这些都很好获取,唯独 POST 请求无法获取其中的 RequestBody。

原因很明显,RequestBody 是只能读取一次的,如果在拦截器中读取了,就无法通过 @RequestBody 注解去获取,因为这个数据是内存中的流数据。

这时候明显需要使用到 AOP 了

利用 AOP 读取 RequestBody

AOP 就是用来做切面的,具体概念就不说了,这里就只讲解具体问题的思路。

这里用 AOP 去切入 Controller 里面所有 public 的方法,利用 JoinPoint 获取参数,从而得到 RequestBody.

得到 RequestBody 后使用 Spring Boot 的日志打印

创建一个切面

  1. @Aspect
  2. @Component
  3. public class JPushAspect {
  • @Aspect 注解表明这是一个切面
  • @Component 注册为组件,否则无法使用 Spring Boot 的日志

声明一个 logger

  1. private final Logger logger = LoggerFactory.getLogger(this.getClass());
  • 这里的 log 与 LogFactory 均在 org.slf4j.LoggerFactory 包下

声明切点

  1. /** 定义切点Pointcut */
  2. @Pointcut("@annotation(com.cutecatos.common.annotation.JPush)")
  3. public void excudeService() {
  4. }

编写 @AfterReturing 获取参数和返回结果

  1. @AfterReturning(returning="rvt", pointcut="excudeService()")
  2. public Object AfterExec(JoinPoint point, Object rvt){
  3. Object[] args = point.getArgs();
  4. Object o = args[0];
  5. for (Object arg : args) {
  6. logger.info("arg: " + arg);
  7. }
  8. //pointcut是对应的注解类 rvt就是方法运行完之后要返回的值
  9. logger.info("AfterReturning增强:获取目标方法的返回值:" + rvt);
  10. JSONObject jsonObject = JSON.parseObject(JSON.toJSONString(rvt));
  11. int code = Integer.parseInt(jsonObject.get("code").toString());
  12. if (code==200){
  13. logger.info("成功");
  14. }else{
  15. logger.info("失败");
  16. }
  17. return rvt;
  18. }
  • JoinPoint.getArgs() 可以得到目标方法的参数,返回类型为 Object[]
  • RequestBody 作为参数时,因为是在调用方法前已经被 Spring 读取并解析了,所以不存在重复读取的问题,调用目标方法结束时,AfterReturning 的 AOP 被执行,拿到传递给目标的参数
  • 同时使用 returning 表明我们返回参数的对象,可以根据实际的业务来对该对象进行逻辑处理,例如:更新前后的记录。。

相关

发表评论

表情:
评论列表 (有 0 条评论,158人围观)

还没有评论,来说两句吧...

相关阅读

    相关 postman获取返回

    在实现接口自动测试的时候,会经常遇到接口参数依赖的问题,例如调取登录接口的时候,需要先获取登录的key值,而每次请求返回的key值又是不一样的,那么这种情况下,要实现接口的自