赞
踩
@Slf4j
public class MartinOAuth2FeignRequestInterceptor implements RequestInterceptor {
。。。
@Override
public void apply(RequestTemplate requestTemplate) {
ServletRequestAttributes attributes = (ServletRequestAttributes) RequestContextHolder.currentRequestAttributes();
HttpServletRequest request = attributes.getRequest();
。。。
}
在使用feign的RequestInterceptor 在服务间传递参数时,RequestContextHolder.currentRequestAttributes()报空指针异常
java.lang.IllegalStateException: No thread-bound request found: Are you referring to request attributes outside of an actual web request, or processing a request outside of the originally receiving thread? If you are actually operating within a web request and still receive this message, your code is probably running outside of DispatcherServlet: In this case, use RequestContextListener or RequestContextFilter to expose the current request.
at org.springframework.web.context.request.RequestContextHolder.currentRequestAttributes(RequestContextHolder.java:131)
at com.java2e.martin.common.security.interceptor.MartinOAuth2FeignRequestInterceptor.apply(MartinOAuth2FeignRequestInterceptor.java:27)
at feign.SynchronousMethodHandler.targetRequest(SynchronousMethodHandler.java:169)
at feign.SynchronousMethodHandler.executeAndDecode(SynchronousMethodHandler.java:99)
at feign.SynchronousMethodHandler.invoke(SynchronousMethodHandler.java:78)
at feign.ReflectiveFeign$FeignInvocationHandler.invoke(ReflectiveFeign.java:103)
at com.sun.proxy.$Proxy185.addSystemLog(Unknown Source)
at com.java2e.martin.common.log.event.LogListener.saveLog(LogListener.java:31)
at com.java2e.martin.common.log.event.LogListener$$FastClassBySpringCGLIB$$5172b67e.invoke(<generated>)
at org.springframework.cglib.proxy.MethodProxy.invoke(MethodProxy.java:218)
at org.springframework.aop.framework.CglibAopProxy$CglibMethodInvocation.invokeJoinpoint(CglibAopProxy.java:749)
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:163)
at org.springframework.aop.interceptor.AsyncExecutionInterceptor.lambda$invoke$0(AsyncExecutionInterceptor.java:115)
at java.util.concurrent.FutureTask.run$$$capture(FutureTask.java:266)
at java.util.concurrent.FutureTask.run(FutureTask.java)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1149)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:624)
at java.lang.Thread.run(Thread.java:748)
RequestContextHolder将当前线程中的request信息存储在ThreadLocal中,开启另外一个线程异步调用feign,httpRequest是绑定在ThreadLocal中的,只能在当前线程中共享,子线程是不能获取到父线程的属性。
1、取消异步调用,改为同步调用,如果用的注解,去掉 @Async即可
2、沿用异步调用,但是在调用前,把父线程request信息绑定给子线程,在方法执行的前面,加入以下语句
RequestContextHolder.setRequestAttributes(RequestContextHolder.getRequestAttributes(), true);
第二个方案应该也能修复 hystrix 使用线程池导致的RequestContextHolder.currentRequestAttributes()为NULL
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。