在使用反射进行调用controller的查询方法进行导出时,被框架配置的web拦截器拦截,
@Pointcut("execution(public * com.meditrusthealth.fast..controller.*.*(..))")
public void fastExpression() {
}```
真正拦截器的作用是使controller层只能被web进行调用;
但是因为表达式public * com.meditrusthealth.fast..controller.*.*(..)),只能拦截到controller下的类及类里边的所有方法,
在开发中我们对controller是按照功能进行划分的,"controller.*.*(..)"并不能像"controller..*.*(..)"这样拦截到我们的子孙包,
所以导致我们开发的公用导出方法一直隐藏一个问题.
直到有一次开发的controller直接放在了controller包下,在这个controller中使用了我们的导出公用方法,
此时问题就暴露出来了,我们正常查询,正常导出都可以,但是当我们的导出大批量数据需要使用异步去处理时,调用invoke方法失败了,
通过排查发现web拦截器中下边的代码:
```java
@Around("fastExpression()")
public Object argsLog(ProceedingJoinPoint point) throws Throwable {
Stopwatch watch = Stopwatch.createStarted();
String methodName = point.getSignature().getName();
RequestAttributes ra = RequestContextHolder.getRequestAttributes();
if (ra == null) {
return new Object();
}
这是异常出现的地方,RequestAttributes丢失了或者说被删除了.
解决方法:
1,使用我们公用导出方法直接调用service中的方法;
2,将我们的controller放到controller下包中;
3,既然RequestAttributes不存在了,那我们就在调用invoke方法之前先自己判断一下,如果不存在的话,我们自己给他设置进入;
因为以上两种方法只是让使用者去进行适配调整,并不妥当,最终我们使用了第三种方案进行处理.
RequestAttributes attributes = RequestContextHolder.getRequestAttributes();
if (attributes == null){
RequestContextHolder.setRequestAttributes(requestAttributes);
}