文章目录
-
-
-
- 一、框架版本
- 二、源码展示
- 三、问题描述
- 四、解决方案
-
-
一、框架版本
-
Spring Boot、 Spring Cloud 、 Spring Cloud Alibaba
框架名称 框架版本 Spring Boot 2.2.5.RELEASE Spring Cloud Hoxton.SR3 Spring Cloud Alibaba 2.2.1.RELEASE
二、源码展示
-
远程鉴权
Controller
控制器代码片段@RestController @Slf4j @RequestMapping("/security") public class AuthenticationController { @Resourceprivate AuthenticationService authenticationService;@PostMapping("/auth")public Boolean checkAuth(@RequestBody @Valid BaseRequest baseRequest) { log.info("<-------------------------->");return authenticationService.checkAuth(baseRequest);} }
-
网关引用
OpenFeign
依赖<!-- OpenFeign --> <dependency><groupId>org.springframework.cloud</groupId><artifactId>spring-cloud-starter-openfeign</artifactId><version>2.2.2.RELEASE</version> </dependency>
-
网关
OpenFeign
调用客户端@Component @FeignClient(value = "rms-security-service") public interface InvokeSecurityServiceClient { @PostMapping("/security/auth")Boolean checkAuth(BaseRequest baseRequest); }
三、问题描述
??在网关层进行统一鉴权和认证的过程中,需要远程调用鉴权服务器的接口进行鉴权的操作。但是在采用 OpenFiegn
进行远程调用的过程中,出现了如下的报错堆栈,导致了远程调用失败
-
堆栈信息
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:
-
关键信息
No qualifying bean of type 'org.springframework.boot.autoconfigure.http.HttpMessageConverters
四、解决方案
-
堆栈分析
HttpMessageConverters
没有被注入到容器中管理 -
ISSUES
跟踪点击此处 查看
issues
信息 -
解决方案
-
源码:
HttpMessageConverters.java
中没有发现异常,于是开始查看是否存在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
不会自动注入。于是自己在配置文件中,直接复制源码的Bean
,最终成功。# 新建配置类 @Configuration public class WebFluxWithOpenFeignConfig { @Bean@ConditionalOnMissingBeanpublic HttpMessageConverters messageConverters(ObjectProvider<HttpMessageConverter<?>> converters) { return new HttpMessageConverters(converters.orderedStream().collect(Collectors.toList()));} }
-