解決SpringCloud Gateway采用OpenFeign遠程調(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 |
二、源碼展示
遠程鑒權(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)層進行統(tǒng)一鑒權(quán)和認證的過程中,需要遠程調(diào)用鑒權(quán)服務(wù)器的接口進行鑒權(quán)的操作。
但是在采用 OpenFiegn 進行遠程調(diào)用的過程中,出現(xiàn)了如下的報錯堆棧,導(dǎo)致了遠程調(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跟蹤- 點擊此處 查看
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 新提供的注解,它的作用是按照一定的條件進行判斷,滿足條件給容器注冊 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 不會自動注入。
于是自己在配置文件中,直接復(fù)制源碼的 Bean,最終成功。
# 新建配置類
@Configuration
public class WebFluxWithOpenFeignConfig {
@Bean
@ConditionalOnMissingBean
public HttpMessageConverters messageConverters(ObjectProvider<HttpMessageConverter<?>> converters) {
return new HttpMessageConverters(converters.orderedStream().collect(Collectors.toList()));
}
}總結(jié)
以上為個人經(jīng)驗,希望能給大家一個參考,也希望大家多多支持腳本之家。
相關(guān)文章
springboot2.0+elasticsearch5.5+rabbitmq搭建搜索服務(wù)的坑
這篇文章主要介紹了springboot2.0+elasticsearch5.5+rabbitmq搭建搜索服務(wù)的坑,小編覺得挺不錯的,現(xiàn)在分享給大家,也給大家做個參考。一起跟隨小編過來看看吧2018-06-06
SpringBoot整合mybatis結(jié)合pageHelper插件實現(xiàn)分頁
在本篇文章里小編給大家整理的是關(guān)于SpringBoot整合mybatis使用pageHelper插件進行分頁操作相關(guān)知識點,需要的朋友們學習下。2020-02-02
Spring使用AOP完成統(tǒng)一結(jié)果封裝實例demo
這篇文章主要介紹了Spring使用AOP完成統(tǒng)一結(jié)果封裝,本文通過實現(xiàn)demo給大家詳細講解,代碼簡單易懂,對大家的學習或工作具有一定的參考借鑒價值,需要的朋友可以參考下2023-02-02
Spring Cloud Consul的服務(wù)注冊與發(fā)現(xiàn)
這篇文章主要介紹了Spring Cloud Consul服務(wù)注冊與發(fā)現(xiàn)的實現(xiàn)方法,幫助大家更好的理解和學習使用spring框架,感興趣的朋友可以了解下2021-02-02

