spring 多线程 或者异步 Feign 调用其他微服务 拦截时取不到request的情况

报错信息:

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/DispatcherPortlet: In this case, use RequestContextListener or RequestContextFilter to expose the current request.

 

场景:在Mq的监听中,去调用其他的微服务,在对Feign进行拦截的时候报错

spring 多线程 或者异步 Feign 调用其他微服务 拦截时取不到request的情况_第1张图片

在链路拦截日志的RequestInterceptor中,我们可以看到通过下面方法,没有取得request的信息

RequestContextHolder.currentRequestAttributes()

spring 多线程 或者异步 Feign 调用其他微服务 拦截时取不到request的情况_第2张图片

spring 多线程 或者异步 Feign 调用其他微服务 拦截时取不到request的情况_第3张图片

 通过源码可以查看到是从当前ThreadLocal 中获取上下文的RequestAtrributes

 

spring 多线程 或者异步 Feign 调用其他微服务 拦截时取不到request的情况_第4张图片

 当拿不到request时,创建NonWebRequestAttributes来实现RequestAttributes,然后加一个非空判断绕过强转的地方,这样就能正常的调用其他服务了


@Component
public class LogFeignInterceptor implements RequestInterceptor {
    public LogFeignInterceptor() {
    }

    public void apply(RequestTemplate requestTemplate) {
        HttpServletRequest httpRequest = this.getHttpServletRequestSafely();
        if (null != httpRequest && null != httpRequest.getAttribute("X-Request-No")) {
            requestTemplate.header("X-Request-No", new String[]{httpRequest.getAttribute("X-Request-No").toString()});
        }

    }

    public HttpServletRequest getHttpServletRequestSafely() {
        try {
            RequestAttributes requestAttributesSafely = this.getRequestAttributesSafely();
            return requestAttributesSafely instanceof NonWebRequestAttributes ? null : ((ServletRequestAttributes)requestAttributesSafely).getRequest();
        } catch (Exception var2) {
            return null;
        }
    }

    public RequestAttributes getRequestAttributesSafely() {
        Object requestAttributes = null;

        try {
            requestAttributes = RequestContextHolder.currentRequestAttributes();
        } catch (IllegalStateException var3) {
            requestAttributes = new NonWebRequestAttributes();
        }

        return (RequestAttributes)requestAttributes;
    }
}

spring 多线程 或者异步 Feign 调用其他微服务 拦截时取不到request的情况_第5张图片

你可能感兴趣的:(java)