解決SpringCloud Gateway采用OpenFeign遠(yuǎn)程調(diào)用失敗的問題
一、框架版本
Spring Boot、 Spring Cloud 、 Spring Cloud Alibaba
框架名稱 | 框架版本 |
---|---|
Spring Boot | 2.2.5.RELEASE |
Spring Cloud | Hoxton.SR3 |
Spring Cloud Alibaba | 2.2.1.RELEASE |
二、源碼展示
遠(yuǎn)程鑒權(quán) Controller
控制器代碼片段
@RestController @Slf4j @RequestMapping("/security") public class AuthenticationController { @Resource private AuthenticationService authenticationService; @PostMapping("/auth") public Boolean checkAuth(@RequestBody @Valid BaseRequest baseRequest) { log.info("<-------------------------->"); return authenticationService.checkAuth(baseRequest); } }
網(wǎng)關(guān)引用 OpenFeign
依賴
<!-- OpenFeign --> <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter-openfeign</artifactId> <version>2.2.2.RELEASE</version> </dependency>
網(wǎng)關(guān) OpenFeign
調(diào)用客戶端
@Component @FeignClient(value = "rms-security-service") public interface InvokeSecurityServiceClient { @PostMapping("/security/auth") Boolean checkAuth(BaseRequest baseRequest); }
三、問題描述
在網(wǎng)關(guān)層進(jìn)行統(tǒng)一鑒權(quán)和認(rèn)證的過程中,需要遠(yuǎn)程調(diào)用鑒權(quán)服務(wù)器的接口進(jìn)行鑒權(quán)的操作。
但是在采用 OpenFiegn
進(jìn)行遠(yuǎn)程調(diào)用的過程中,出現(xiàn)了如下的報(bào)錯(cuò)堆棧,導(dǎo)致了遠(yuǎn)程調(diào)用失敗
- 堆棧信息
feign.codec.EncodeException: 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:384)
Suppressed: reactor.core.publisher.FluxOnAssembly$OnAssemblyException:
Error has been observed at the following site(s):
|_ checkpoint ? org.springframework.security.web.server.authorization.AuthorizationWebFilter [DefaultWebFilterChain]
|_ checkpoint ? org.springframework.security.web.server.authorization.ExceptionTranslationWebFilter [DefaultWebFilterChain]
|_ checkpoint ? org.springframework.security.web.server.authentication.logout.LogoutWebFilter [DefaultWebFilterChain]
|_ checkpoint ? org.springframework.security.web.server.savedrequest.ServerRequestCacheWebFilter [DefaultWebFilterChain]
|_ checkpoint ? org.springframework.security.web.server.context.SecurityContextServerWebExchangeWebFilter [DefaultWebFilterChain]
|_ checkpoint ? org.springframework.security.web.server.authentication.AuthenticationWebFilter [DefaultWebFilterChain]
|_ checkpoint ? org.springframework.security.web.server.context.ReactorContextWebFilter [DefaultWebFilterChain]
|_ checkpoint ? cn.com.jstec.open.cloud.gateway.config.SecurityConfig$$Lambda$772/0x0000016c006c3040 [DefaultWebFilterChain]
|_ checkpoint ? org.springframework.security.web.server.header.HttpHeaderWriterWebFilter [DefaultWebFilterChain]
|_ checkpoint ? org.springframework.security.config.web.server.ServerHttpSecurity$ServerWebExchangeReactorContextWebFilter [DefaultWebFilterChain]
|_ checkpoint ? org.springframework.security.web.server.WebFilterChainProxy [DefaultWebFilterChain]
|_ checkpoint ? org.springframework.boot.actuate.metrics.web.reactive.server.MetricsWebFilter [DefaultWebFilterChain]
|_ checkpoint ? HTTP GET "/open-platform/achievement/list?page=1" [ExceptionHandlingWebHandler]
Stack trace:
- 關(guān)鍵信息
No qualifying bean of type 'org.springframework.boot.autoconfigure.http.HttpMessageConverters
四、解決方案
堆棧分析
HttpMessageConverters
沒有被注入到容器中管理ISSUES
跟蹤- 點(diǎn)擊此處 查看
issues
信息
解決方案
源碼:HttpMessageConverters.java
中沒有發(fā)現(xiàn)異常,于是開始查看是否存在 AutoConfiguration
打開 HttpMessageConvertersAutoConfiguration.java
@Configuration(proxyBeanMethods = false) @ConditionalOnClass(HttpMessageConverter.class) @Conditional(NotReactiveWebApplicationCondition.class) @AutoConfigureAfter({ GsonAutoConfiguration.class, JacksonAutoConfiguration.class, JsonbAutoConfiguration.class }) @Import({ JacksonHttpMessageConvertersConfiguration.class, GsonHttpMessageConvertersConfiguration.class, JsonbHttpMessageConvertersConfiguration.class }) public class HttpMessageConvertersAutoConfiguration { }
源碼:@Conditional(NotReactiveWebApplicationCondition.class)
@Conditional
是 Spring4
新提供的注解,它的作用是按照一定的條件進(jìn)行判斷,滿足條件給容器注冊(cè) bean
再查看類 NotReactiveWebApplicationCondition
static class NotReactiveWebApplicationCondition extends NoneNestedConditions { NotReactiveWebApplicationCondition() { super(ConfigurationPhase.PARSE_CONFIGURATION); } @ConditionalOnWebApplication(type = Type.REACTIVE) private static class ReactiveWebApplication { } }
Spring Cloud Gateway
是基于 WebFlux
的,是 ReactiveWeb
,所以 HttpMessageConverters
不會(huì)自動(dòng)注入。
于是自己在配置文件中,直接復(fù)制源碼的 Bean
,最終成功。
# 新建配置類 @Configuration public class WebFluxWithOpenFeignConfig { @Bean @ConditionalOnMissingBean public HttpMessageConverters messageConverters(ObjectProvider<HttpMessageConverter<?>> converters) { return new HttpMessageConverters(converters.orderedStream().collect(Collectors.toList())); } }
總結(jié)
以上為個(gè)人經(jīng)驗(yàn),希望能給大家一個(gè)參考,也希望大家多多支持腳本之家。
相關(guān)文章
springboot2.0+elasticsearch5.5+rabbitmq搭建搜索服務(wù)的坑
這篇文章主要介紹了springboot2.0+elasticsearch5.5+rabbitmq搭建搜索服務(wù)的坑,小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過來看看吧2018-06-06SpringBoot整合mybatis結(jié)合pageHelper插件實(shí)現(xiàn)分頁
在本篇文章里小編給大家整理的是關(guān)于SpringBoot整合mybatis使用pageHelper插件進(jìn)行分頁操作相關(guān)知識(shí)點(diǎn),需要的朋友們學(xué)習(xí)下。2020-02-02Spring使用AOP完成統(tǒng)一結(jié)果封裝實(shí)例demo
這篇文章主要介紹了Spring使用AOP完成統(tǒng)一結(jié)果封裝,本文通過實(shí)現(xiàn)demo給大家詳細(xì)講解,代碼簡(jiǎn)單易懂,對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下2023-02-02Java實(shí)現(xiàn)用戶短信驗(yàn)證碼登錄功能實(shí)例代碼
現(xiàn)在不管是各類的網(wǎng)站,還是大小社交app,登錄方式是越來越多了,但是大部分還是以短信登錄為主,本文主要介紹了java短信驗(yàn)證碼登錄功能設(shè)計(jì)與實(shí)現(xiàn),感興趣的可以了解一下2021-11-11Spring Cloud Consul的服務(wù)注冊(cè)與發(fā)現(xiàn)
這篇文章主要介紹了Spring Cloud Consul服務(wù)注冊(cè)與發(fā)現(xiàn)的實(shí)現(xiàn)方法,幫助大家更好的理解和學(xué)習(xí)使用spring框架,感興趣的朋友可以了解下2021-02-02