使用AOP获取RequestBody
目录
一开始使用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被执行,拿到传递给目标的参数