gateWay通过feign调用其他服务错误

问题描述:
通过网关拦截器统一认证人员信息,如:获取可以访问的url进行校验,需要使用feign调用资源服务获取资源。但是网关使用feign报错:HttpMessageConverters注入失败

环境:
springCloud(Hoxton.RELEASE),jdk(1.8),springBoot(2.2.1)

场景:
在网关拦截器中使用feign调用其他服务:

public Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) {
/*****/
Object obj= XXXFeign.getXXX(XXXDTO).getData();
}

错误信息:

 No qualifying bean of type 'org.springframework.boot.autoconfigure.http.HttpMessageConverters' available: expected at least 1 bean which qualifies as autowire candidate. Dependency annotations: {@org.springframework.beans.factory.annotation.Autowired(required=true)}
        at feign.ReflectiveFeign$BuildEncodedTemplateFromArgs.resolve(ReflectiveFeign.java:376) ~[feign-core-10.4.0.jar!/:na]
        Suppressed: reactor.core.publisher.FluxOnAssembly$OnAssemblyException:
Error has been observed at the following site(s):
        |_ checkpoint ⇢ org.springframework.cloud.gateway.filter.WeightCalculatorWebFilter [DefaultWebFilterChain]
        |_ checkpoint ⇢ HTTP GET "/api/admin/baseUsers/info" [ExceptionHandlingWebHandler]
Stack trace:.
                at feign.ReflectiveFeign$BuildEncodedTemplateFromArgs.resolve(ReflectiveFeign.java:376) ~[feign-core-10.4.0.jar!/:na]
                at feign.ReflectiveFeign$BuildTemplateByResolvingArgs.create(ReflectiveFeign.java:224) ~[feign-core-10.4.0.jar!/:na]
                at feign.SynchronousMethodHandler.invoke(SynchronousMethodHandler.java:75) ~[feign-core-10.4.0.jar!/:na]
                at feign.ReflectiveFeign$FeignInvocationHandler.invoke(ReflectiveFeign.java:103) ~[feign-core-10.4.0.jar!/:na]
                at com.sun.proxy.$Proxy90.getUserButtons(Unknown Source) ~[na:na]
                at com.xzb.springcloud.gateway.filter.RoleAuthFilter.filter(RoleAuthFilter.java:105) ~[classes!/:0.0.1-SNAPSHOT]
                at org.springframework.cloud.gateway.handler.FilteringWebHandler$GatewayFilterAdapter.filter(FilteringWebHandler.java:138) ~[spring-cloud-gateway-core-2.2.0.RELEASE.jar!/:2.2.0.RELEASE]
                at org.springframework.cloud.gateway.filter.OrderedGatewayFilter.filter(OrderedGatewayFilter.java:44) ~[spring-cloud-gateway-core-2.2.0.RELEASE.jar!/:2.2.0.RELEASE]
                at org.springframework.cloud.gateway.handler.FilteringWebHandler$DefaultGatewayFilterChain.lambda$filter$0(FilteringWebHandler.java:118) ~[spring-cloud-gateway-core-2.2.0.RELEASE.jar!/:2.2.0.RELEASE]
                at org.springframework.cloud.gateway.handler.FilteringWebHandler$DefaultGatewayFilterChain$$Lambda$788/242982330.get(Unknown Source) ~[na:na]
                at reactor.core.publisher.MonoDefer.subscribe(MonoDefer.java:44) [reactor-core-3.3.0.RELEASE.jar!/:3.3.0.RELEASE]
                at reactor.core.publisher.Mono.subscribe(Mono.java:4087) [reactor-core-3.3.0.RELEASE.jar!/:3.3.0.RELEASE]

分析:
通过日志可见HttpMessageConverters注入失败。
查看源码:
在HTTP协议不是很规范的情况下,需要配置Decoder在HTTP协议不是很规范的情况下,需要配置Decoder
解决:
**1.**添加配置类(此代码,百度一搜一大堆,直接去粘贴就可以了):

@SpringBootConfiguration
public class FeignConfig {
    @Bean
    public Decoder feignDecoder() {
        return new ResponseEntityDecoder(new SpringDecoder(feignHttpMessageConverter()));
    }

    public ObjectFactory<HttpMessageConverters> feignHttpMessageConverter() {
        final HttpMessageConverters httpMessageConverters = new HttpMessageConverters(new GateWayMappingJackson2HttpMessageConverter());
        return new ObjectFactory<HttpMessageConverters>() {
            @Override
            public HttpMessageConverters getObject() throws BeansException {
                return httpMessageConverters;
            }
        };
    }

    public class GateWayMappingJackson2HttpMessageConverter extends MappingJackson2HttpMessageConverter {
        GateWayMappingJackson2HttpMessageConverter() {
            List<MediaType> mediaTypes = new ArrayList<>();
            mediaTypes.add(MediaType.valueOf(MediaType.TEXT_HTML_VALUE + ";charset=UTF-8"));
            setSupportedMediaTypes(mediaTypes);
        }
    }
}

可能是因为cloud版本的问题问题并没有解决,网上有说Greenwich.SR3下运行正常。

扩展:知道了原因后分析:HttpMessageConvertersAutoConfiguration这个类有个自动注入的条件的:@Conditional(NotReactiveWebApplicationCondition.class)
意思是非响应式服务的web才可以注入。
响应式服务相关知识自行百度
参考:https://blog.csdn.net/varyall/article/details/104243016(转发)

**2.**继续解决问题,既然没有初始化注入,那就手动初始化注入一下子,代码如下(添加配置):

@Configuration
public class HttpMsgConverConfig {
    @Bean
    KeyResolver userKeyResolver() {
        return exchange -> Mono.just(Objects.requireNonNull(exchange.getRequest().getRemoteAddress()).getAddress().getHostAddress());
    }

    @Bean
    @ConditionalOnMissingBean
    public HttpMessageConverters messageConverters(ObjectProvider<HttpMessageConverter<?>> converters) {
        return new HttpMessageConverters(converters.orderedStream().collect(Collectors.toList()));
    }
}

问题解决。

猜你喜欢

转载自blog.csdn.net/weixin_41546244/article/details/107865756