使用AOP获取RequestBody
原文链接 http://blog.gaoyuexiang.cn/get_RequestBody_by_aop/
注:以下为加速网络访问所做的原文缓存,经过重新格式化,可能存在格式方面的问题,或偶有遗漏信息,请以原文为准。
- doc {:toc}
一开始使用spring拦截器
拦截请求记录日志,对于请求路径、header这些都很好获取,唯独POST
请求无法获取其中的RequestBody
.
原因很明显,RequestBody
是只能读取一次的,如果在拦截器中读取了,就无法通过@RequestBody
注解去获取,因为这个数据是内存中的流数据.
那要如何做呢?明显就需要用到aop
了
利用AOP
读取RequestBody
aop
就是用来做切面的,具体概念这里不说了,自行谷歌.这里就讲具体问题的思路.
这里用aop
去切入Controller
里面所有public
的方法,利用JoinPoint
获取参数,从而得到RequestBody
.
得到RequestBody
后使用Spring Boot
的日志打印
创建一个切面
@Aspect
@Component
public class RequestMapAspect {}
@Aspect
注解表明这是一个切面@Componet
注册为组件,否则无法使用Spring Boot
的日志
声明一个logger
private final Log log = LogFactory(this.getClass());
- 这里的
Log
与LogFactory
均在org.apache.commons.logging
包下,不是slf4j
,不是logback
也不是log4j
!
声明切点
@Pointcut(value = "excution(public * cn.gaoyuexiang.controller.*.*(..))")
public void controllerLog() {}
编写Before
获取参数
@Before("controllerLog()")
public void before(JoinPoint point) {
logger.info("controller aspect begging");
Object[] args = point.getArgs();
for (Object arg : args) {
logger.info("arg: " + arg);
}
String method = point.getSignature().getDeclaringTypeName() + '.' + point.getSignature().getName();
logger.info("aspect finishing");
logger.info("calling " + method);
}
JoinPoint.getArgs()
可以得到目标方法的参数,返回类型为Object[]
RequestBody
作为参数时,因为是在调用方法前已经被Spring
读取并解析了,所以不存在重复读取的问题.调用目标方法时,Before
的aop
被执行,拿到传递给目标的参数