webservice调用springcloud微服务体系,feign内部报错

这个问题本身没什么太大价值,但是查了很久所以记录和发泄一下:

feign.RetryableException: null executing GET http://****/cr**t/e**/cre****ount/2**8060
at feign.FeignException.errorExecuting(FeignException.java:132)
at feign.SynchronousMethodHandler.executeAndDecode(SynchronousMethodHandler.java:113)
at feign.SynchronousMethodHandler.invoke(SynchronousMethodHandler.java:78)
at feign.ReflectiveFeign$FeignInvocationHandler.invoke(ReflectiveFeign.java:103)
at com.sun.proxy.$Proxy189.getCustomerCredit4Ebs(Unknown Source)
at com.crpt.biz.service.impl.ebs.QueryCustomeCreditService.execute(QueryCustomeCreditService.java:56)
at com.crpt.biz.service.impl.ebs.QueryCustomeCreditService.execute(QueryCustomeCreditService.java:23)
at com.crpt.biz.ebs.webservice.CrptEBSService.request(CrptEBSService.java:92)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:498)
at org.apache.cxf.service.invoker.AbstractInvoker.performInvocation(AbstractInvoker.java:179)
at org.apache.cxf.jaxws.JAXWSMethodInvoker.performInvocation(JAXWSMethodInvoker.java:66)
at org.apache.cxf.service.invoker.AbstractInvoker.invoke(AbstractInvoker.java:96)
at org.apache.cxf.jaxws.AbstractJAXWSMethodInvoker.invoke(AbstractJAXWSMethodInvoker.java:232)
at org.apache.cxf.jaxws.JAXWSMethodInvoker.invoke(JAXWSMethodInvoker.java:85)
at org.apache.cxf.service.invoker.AbstractInvoker.invoke(AbstractInvoker.java:74)
at org.apache.cxf.interceptor.ServiceInvokerInterceptor$1.run(ServiceInvokerInterceptor.java:59)
at java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:511)
at java.util.concurrent.FutureTask.run(FutureTask.java:266)

CXF能够正常接入数据,但是接入后调用微服务内部的feign报错

原因webservice客户端请求时,携带了这个header信息:transfer-encoding:chunked

而springcloud会把请求过来的http header信息转嫁给下一次发生调用的feign中,源码详见feign.SynchronousMethodHandler#targetRequest

这样就需要我们定值一个RequestInterceptor去简化一下header

@Component
@Slf4j
public class FeignRequestInterceptor implements RequestInterceptor {
final static String TRANSFER_ENCODING = "transfer-encoding";

@Override
public void apply(RequestTemplate requestTemplate) {
    ServletRequestAttributes attributes = (ServletRequestAttributes) RequestContextHolder.getRequestAttributes();
    if(attributes==null)
        return ;
    HttpServletRequest request= attributes.getRequest();
    Enumeration<String> headerNames = request.getHeaderNames();
    
    if (headerNames != null) {
        while (headerNames.hasMoreElements()) {
            String name = headerNames.nextElement();
            String values = request.getHeader(name);
    
            if(isOverLapHeader(requestTemplate,name))
                requestTemplate.header(name, values);
        }
    }
}
//是否允许覆盖requestTemplate中的header
private boolean isOverLapHeader(RequestTemplate requestTemplate,String headerName)
{
    Map<String, Collection<String>> headers= requestTemplate.headers();
    if(headers==null)
    {
        return true;
    }
    if (TRANSFER_ENCODING.equalsIgnoreCase(headerName)) {
        return false;
    }
    return true;

}

这样内部的feign调用时就不会有问题了

原文地址:https://www.cnblogs.com/zxporz/p/13094614.html