由于 gateway 采用 spring-boot-starter-webflux 异步的 web 组件,该组件和 spring-boot-starter-web 有较大区别,我们的 openFeign 对 spring-boot-starter-web 比较契合,而对于 前者则需要做一些适配。
编写如下配置类
@SpringBootConfiguration
public class FeignConfig {@Beanpublic Decoder feignDecoder() {return new ResponseEntityDecoder(new SpringDecoder(feignHttpMessageConverter()));}public ObjectFactory<HttpMessageConverters> feignHttpMessageConverter() {final HttpMessageConverters httpMessageConverters = new HttpMessageConverters(new GateWayMappingJackson2HttpMessageConverter());return new ObjectFactory<HttpMessageConverters>() {@Overridepublic 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);}}
}
@Configuration
public class HttpMsgConverConfig {@BeanKeyResolver userKeyResolver() {return exchange -> Mono.just(Objects.requireNonNull(exchange.getRequest().getRemoteAddress()).getAddress().getHostAddress());}@Bean@ConditionalOnMissingBeanpublic HttpMessageConverters messageConverters(ObjectProvider<HttpMessageConverter<?>> converters) {return new HttpMessageConverters(converters.orderedStream().collect(Collectors.toList()));}
}
因为 gateway 是异步,而 FeignClient 是同步请求,同步请求在 gateway 中是不被允许的
所以我们需要采取异步的方式发送请求,这使得我们在调用微服务请求时需要做一个包装
private InterfaceInfo getInterfaceInfo(InterfaceInfo interfaceInfo) {CompletableFuture<InterfaceInfo> future = CompletableFuture.supplyAsync(// 在异步包装内执行我们的微服务请求() -> innerInterfaceInfoClient.getInterfaceInfo(interfaceInfo));try {// 等待相应返回结果InterfaceInfo interfaceInfoDB = future.get(1, TimeUnit.MINUTES);return interfaceInfoDB;} catch (Exception ex) {String msg = "网关检查接口是否存在,发生异常";log.error(msg, ex);throw new RuntimeException(msg);}}