[英]Why HATEOAS starts creating issue for spring-boot version >= 2.2.x during startup with Swagger 2.x?
I moved my project from spring-boot 2.1.9 to 2.2.0.我将我的项目从 spring-boot 2.1.9 移至 2.2.0。
While starting the project, I am facing the below error
messages.在启动项目时,我面临以下error
消息。
Caused by: org.springframework.beans.factory.NoUniqueBeanDefinitionException: No qualifying bean of type 'org.springframework.plugin.core.PluginRegistry<org.springframework.hateoas.client.LinkDiscoverer, org.springframework.http.MediaType>' available: expected single matching bean but found 17: modelBuilderPluginRegistry,modelPropertyBuilderPluginRegistry,typeNameProviderPluginRegistry,syntheticModelProviderPluginRegistry,documentationPluginRegistry,apiListingBuilderPluginRegistry,operationBuilderPluginRegistry,parameterBuilderPluginRegistry,expandedParameterBuilderPluginRegistry,resourceGroupingStrategyRegistry,operationModelsProviderPluginRegistry,defaultsProviderPluginRegistry,pathDecoratorRegistry,apiListingScannerPluginRegistry,relProviderPluginRegistry,linkDiscovererRegistry,entityLinksPluginRegistry
Caused by: org.springframework.beans.factory.UnsatisfiedDependencyException: Error creating bean with name 'linkDiscoverers' defined in class path resource [org/springframework/hateoas/config/HateoasConfiguration.class]: Unsatisfied dependency expressed through method 'linkDiscoverers' parameter 0; nested exception is org.springframework.beans.factory.NoUniqueBeanDefinitionException: No qualifying bean of type 'org.springframework.plugin.core.PluginRegistry<org.springframework.hateoas.client.LinkDiscoverer, org.springframework.http.MediaType>' available: expected single matching bean but found 17: modelBuilderPluginRegistry,modelPropertyBuilderPluginRegistry,typeNameProviderPluginRegistry,syntheticModelProviderPluginRegistry,documentationPluginRegistry,apiListingBuilderPluginRegistry,operationBuilderPluginRegistry,parameterBuilderPluginRegistry,expandedParameterBuilderPluginRegistry,resourceGroupingStrategyRegistry,operationModelsProviderPluginRegistry,defaultsProviderPluginRegistry,pathDecoratorRegistry,apiListingScannerPluginRegistry,relProviderPluginRegistry,linkDiscovererRegistry,entityLinksPluginRegistry
***************************
APPLICATION FAILED TO START
***************************
Description:
Parameter 0 of method linkDiscoverers in org.springframework.hateoas.config.HateoasConfiguration
required a single bean, but 17 were found:
- modelBuilderPluginRegistry: defined in null
- modelPropertyBuilderPluginRegistry: defined in null
- typeNameProviderPluginRegistry: defined in null
- syntheticModelProviderPluginRegistry: defined in null
- documentationPluginRegistry: defined in null
- apiListingBuilderPluginRegistry: defined in null
- operationBuilderPluginRegistry: defined in null
- parameterBuilderPluginRegistry: defined in null
- expandedParameterBuilderPluginRegistry: defined in null
- resourceGroupingStrategyRegistry: defined in null
- operationModelsProviderPluginRegistry: defined in null
- defaultsProviderPluginRegistry: defined in null
- pathDecoratorRegistry: defined in null
- apiListingScannerPluginRegistry: defined in null
- relProviderPluginRegistry: defined by method 'relProviderPluginRegistry' in class path resource [org/springframework/hateoas/config/HateoasConfiguration.class]
- linkDiscovererRegistry: defined in null
- entityLinksPluginRegistry: defined by method 'entityLinksPluginRegistry' in class path resource [org/springframework/hateoas/config/WebMvcEntityLinksConfiguration.class]
What could have caused this issue?是什么导致了这个问题?
Note: I am not using HATEOAS in my pom.xml
file.注意:我没有在我的pom.xml
文件中使用 HATEOAS。
pom.xml pom.xml
<properties>
<java.version>1.8</java.version>
<swagger-springfox.version>2.9.2</swagger-springfox.version>
<sonar.jacoco.execPath>${project.basedir}/target/jacoco.exec</sonar.jacoco.execPath>
<jasypt-spring-boot-starter>2.1.1</jasypt-spring-boot-starter>
<logbook-spring-boot-starter>1.13.0</logbook-spring-boot-starter>
<assertj-swagger>0.8.1</assertj-swagger>
<jacoco-version>0.8.4</jacoco-version>
</properties>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-actuator</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-jpa</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-rest</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-devtools</artifactId>
<scope>runtime</scope>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-configuration-processor</artifactId>
</dependency>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<optional>true</optional>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>io.springfox</groupId>
<artifactId>springfox-swagger2</artifactId>
<version>${swagger-springfox.version}</version>
</dependency>
<dependency>
<groupId>io.springfox</groupId>
<artifactId>springfox-swagger-ui</artifactId>
<version>${swagger-springfox.version}</version>
</dependency>
<dependency>
<groupId>io.springfox</groupId>
<artifactId>springfox-spring-web</artifactId>
<version>${swagger-springfox.version}</version>
</dependency>
<dependency>
<groupId>io.springfox</groupId>
<artifactId>springfox-core</artifactId>
<version>${swagger-springfox.version}</version>
</dependency>
<dependency>
<groupId>io.springfox</groupId>
<artifactId>springfox-data-rest</artifactId>
<version>${swagger-springfox.version}</version>
</dependency>
<dependency>
<groupId>io.springfox</groupId>
<artifactId>springfox-bean-validators</artifactId>
<version>${swagger-springfox.version}</version>
</dependency>
I had this issue with Swagger + HATEOAS
in my spring-boot
application.我在我的spring-boot
应用程序中遇到了Swagger + HATEOAS
这个问题。
The fix is given below (edit your Swagger configuration class):修复如下(编辑您的 Swagger 配置类):
@Configuration
@EnableSwagger2
public class SwaggerConfiguration {
@Bean
public LinkDiscoverers discoverers() {
List<LinkDiscoverer> plugins = new ArrayList<>();
plugins.add(new CollectionJsonLinkDiscoverer());
return new LinkDiscoverers(SimplePluginRegistry.create(plugins));
}
}
For me this link helped: https://github.com/spring-projects/spring-hateoas/issues/731对我来说,这个链接有帮助: https://github.com/spring-projects/spring-hateoas/issues/731
In a nutshell i added to my dependencies:简而言之,我添加了我的依赖项:
<dependency>
<groupId>org.springframework.plugin</groupId>
<artifactId>spring-plugin-core</artifactId>
<version>2.0.0.RELEASE</version>
</dependency>
This kind of issue is occurring due to a new feature of Hateoas.此类问题是由于 Hateoas 的一项新功能而发生的。
If you want to solve this problem, just embed the following line of codes in your swagger configuration file.如果您想解决这个问题,只需在您的 swagger 配置文件中嵌入以下代码行。
@Primary
@Bean
public LinkDiscoverers discoverers() {
List<LinkDiscoverer> plugins = new ArrayList<>();
plugins.add(new CollectionJsonLinkDiscoverer());
return new LinkDiscoverers(SimplePluginRegistry.create(plugins));
}
I think this is gonna solve your problem as it solved mine.我认为这将解决您的问题,因为它解决了我的问题。
The issue faced with me when i using我使用时遇到的问题
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-dependencies</artifactId>
<version>2.2.6.RELEASE</version>
<type>pom</type>
<scope>import</scope>
</dependency>
.....
.....
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-hateoas</artifactId>
</dependency>
with springfox swagger与 springfox swagger
<dependency>
<groupId>io.springfox</groupId>
<artifactId>springfox-swagger2</artifactId>
<version>2.9.2</version>
</dependency>
<dependency>
<groupId>io.springfox</groupId>
<artifactId>springfox-swagger-ui</artifactId>
<version>2.9.2</version>
</dependency>
if you take a look into spring hateoas dependencies there is a dependency on spring-plugin-core
with version 2.0.0.RELEASE
如果您查看 spring hatoas 依赖项,则依赖于版本为2.0.0.RELEASE
spring-plugin-core
<dependency>
<groupId>org.springframework.plugin</groupId>
<artifactId>spring-plugin-core</artifactId>
<version>${spring-plugin.version}</version>
</dependency>
but swagger dependency use spring-plugin-core
with version 1.2.0.RELEASE
.但是 swagger 依赖项使用版本1.2.0.RELEASE
spring-plugin-core
。
spring-boot have conflict on bean creation so, you need to unify the org.springframework.plugin
version to make spring see it, If you choose 2.0.0.RELEASE
swagger will bot be able to compile, spring-boot bean创建有冲突,需要统一org.springframework.plugin
版本才能让spring看到,如果选择2.0.0.RELEASE
Z5DB89E7472F81A4EAF6B77可以编译到FC72
so version 1.2.0.RELEASE
will be work for both dependencies, like所以版本1.2.0.RELEASE
将适用于两个依赖项,比如
<dependency>
<groupId>org.springframework.plugin</groupId>
<artifactId>spring-plugin-core</artifactId>
<version>1.2.0.RELEASE</version>
</dependency>
After that you need configuration class to initiate beans for swagger
and hateoas
like this:之后,您需要配置 class 来为swagger
和hateoas
启动 bean,如下所示:
@EnableSwagger2
@Configuration
public class SwaggerConfiguration {
@Primary
@Bean
public LinkDiscoverers discoverers() {
List<LinkDiscoverer> plugins = new ArrayList<>();
plugins.add(new CollectionJsonLinkDiscoverer());
return new LinkDiscoverers(SimplePluginRegistry.create(plugins));
}
@Bean
public Docket postsApi() {
return new Docket(DocumentationType.SWAGGER_2)
.groupName("{ApplicationName}")
.apiInfo(buildApiInfo())
.select()
.apis(RequestHandlerSelectors.any())
.paths(PathSelectors.regex("/.*"))
.build();
}
private ApiInfo buildApiInfo() {
Contact contact = new Contact("CompanyName", "https://company-domain.com", "mail@company.com");
return new ApiInfoBuilder()
.title(""{ApplicationName}"")
.description("API Description")
.license("license")
.version("1.0")
.contact(contact)
.licenseUrl("licenseURl")
.build();
}
}
try this version 2.6.1,i already solve with this way试试这个版本2.6.1,我已经用这种方式解决了
<dependency>
<groupId>io.springfox</groupId>
<artifactId>springfox-swagger2</artifactId>
<version>2.6.1</version>
</dependency>
<dependency>
<groupId>io.springfox</groupId>
<artifactId>springfox-swagger-ui</artifactId>
<version>2.6.1</version>
</dependency>
For Spring boot version 2.1.3.RELEASE
users, the following dependencies work fine for hateoas+swagger:对于 Spring 启动版本2.1.3.RELEASE
用户,以下依赖项适用于 hatoas+swagger:
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-hateoas</artifactId>
</dependency>
<dependency>
<groupId>io.springfox</groupId>
<artifactId>springfox-swagger2</artifactId>
<version>2.9.2</version>
</dependency>
<dependency>
<groupId>io.springfox</groupId>
<artifactId>springfox-swagger-ui</artifactId>
<version>2.9.2</version>
</dependency>
Use following 2 dependency to resolve Swagger and Hateoas dependency conflict.
If Spring Boot version is >= 2.2.0 the use io.springfox version 3.0.0
<dependency>
<groupId>io.springfox</groupId>
<artifactId>springfox-swagger2</artifactId>
<version>3.0.0</version>
</dependency>
<dependency>
<groupId>io.springfox</groupId>
<artifactId>springfox-swagger-ui</artifactId>
<version>3.0.0</version>
</dependency>
After using version 3.0.0 swagger-ui will not be working so use following dependency and user /swagger-ui/ instead /swagger-ui.html使用 3.0.0 版本后,swagger-ui 将无法正常工作,因此请使用以下依赖项和用户 /swagger-ui/ 而不是 /swagger-ui.html
<dependency>
<groupId>io.springfox</groupId>
<artifactId>springfox-boot-starter</artifactId>
<version>3.0.0</version>
</dependency>
Best Solution最佳解决方案
Add below code in SwaggerConfig class在 SwaggerConfig class 中添加以下代码
@Bean
public LinkDiscoverers discovers() {
List<LinkDiscoverer> plugins = new ArrayList<>();
plugins.add(new CollectionJsonLinkDiscoverer());
return new LinkDiscoverers(SimplePluginRegistry.create(plugins));[enter image description here][1]
}
I was getting error我收到错误
"Error creating bean with name 'halLinkDisocoverer' defined in class path resource [org/springframework/hateoas/mediatype/hal/HalMediaTypeConfiguration.class]".. “在 class 路径资源 [org/springframework/hateoas/mediatype/hal/HalMediaTypeConfiguration.class] 中定义名称为 'halLinkDisocoverer' 的 bean 创建错误”..
While Building a Hypermedia-Driven RESTful Web Service在构建超媒体驱动的 RESTful Web 服务时
Deletion of this dependency删除此依赖项
<dependency>
<groupId>com.jayway.jsonpath</groupId>
<artifactId>json-path</artifactId>
<scope>test</scope>
</dependency>
resolved my issue.解决了我的问题。
Check this link for more details Why i am getting an error Factory method 'halLinkDisocoverer' threw exception in springboot?检查此链接以获取更多详细信息为什么我收到错误工厂方法'halLinkDisocoverer'在springboot中引发异常?
I am using springdoc-openapi and after having encountered this problem similar to the one mentioned here:我正在使用 springdoc-openapi 并在遇到类似于此处提到的问题后:
Description:
Parameter 0 of method linkDiscoverers in org.springframework.hateoas.config.HateoasConfiguration required a single bean, but 3 were found:
- relProviderPluginRegistry: defined by method 'relProviderPluginRegistry' in class path resource [org/springframework/hateoas/config/HateoasConfiguration.class]
- linkDiscovererRegistry: defined in null
- entityLinksPluginRegistry: defined by method 'entityLinksPluginRegistry' in class path resource [org/springframework/hateoas/config/WebMvcEntityLinksConfiguration.class]
Action:
Consider marking one of the beans as @Primary, updating the consumer to accept multiple beans, or using @Qualifier to identify the bean that should be consumed
I just add this dependency in my pom file我只是在我的 pom 文件中添加了这个依赖项
<dependency>
<groupId>org.springframework.hateoas</groupId>
<artifactId>spring-hateoas</artifactId>
<version>1.1.1.RELEASE</version>
</dependency>
hope that this can help someone希望这可以帮助某人
You can change the version like this:您可以像这样更改版本:
<dependency>
<groupId>io.springfox</groupId>
<artifactId>springfox-swagger2</artifactId>
<version>3.0.0</version>
</dependency>
<dependency>
<groupId>io.springfox</groupId>
<artifactId>springfox-swagger-ui</artifactId>
<version>2.8.0</version>
</dependency>
I am working with Spring Boot 2.4.1.我正在使用 Spring Boot 2.4.1。 But you can not see Swagger endpoint log when starting Spring Boot application.但是在启动 Spring 启动应用程序时,您看不到 Swagger 端点日志。
As Alexander Weiß has already answered , the spring-plugin-core
dependency is resolved with the wrong version 1.2.0.RELEASE
.正如Alexander Weiß 已经回答的那样, spring-plugin-core
依赖项已通过错误的版本1.2.0.RELEASE
解决。
In order to force usage of the correct 2.0.0.RELEASE
, you have to EITHER exclude the wrong transitive dependency and explicitly specify the correct one, OR to pin (!) that dependency version in your pom.xml
.为了强制使用正确的2.0.0.RELEASE
,您必须排除错误的传递依赖并明确指定正确的依赖,或者在pom.xml
中固定(!)该依赖版本。 This is done in the <dependenciesManagement>
block, not in the <dependencies>
block.这是在<dependenciesManagement>
块中完成的,而不是在<dependencies>
块中。 Pinning example for Springfox 3.0.0: Springfox 3.0.0 的固定示例:
<properties>
<spring-plugin-core.version>2.0.0.RELEASE</spring-plugin-core.version>
<springfox.version>3.0.0</springfox.version>
</properties>
<dependencyManagement>
<dependencies>
<!-- API Documentation -->
<!-- Fix wrong resolved `spring-plugin-core` dependency version for springfox -->
<dependency>
<groupId>org.springframework.plugin</groupId>
<artifactId>spring-plugin-core</artifactId>
<version>${spring-plugin-core.version}</version>
</dependency>
<dependency>
<groupId>io.springfox</groupId>
<artifactId>springfox-boot-starter</artifactId>
<version>${springfox.version}</version>
</dependency>
</dependencies>
</dependencyManagement>
<dependencies>
<!-- API Documentation -->
<dependency>
<groupId>io.springfox</groupId>
<artifactId>springfox-boot-starter</artifactId>
</dependency>
</dependencies>
So I actually wanted hateoas support and had the same issue.所以我实际上想要仇恨支持并且有同样的问题。 Turned out this happens if you have原来如果你有这种情况
<dependency>
<groupId>org.springframework.hateoas</groupId>
<artifactId>spring-hateoas</artifactId>
</dependency>
instead of代替
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-hateoas</artifactId>
</dependency>
I've removed these dependencies as a workaround and worked:我已经删除了这些依赖项作为解决方法并工作:
<dependency>
<groupId>io.springfox</groupId>
<artifactId>springfox-swagger2</artifactId>
<version>2.4.0</version>
</dependency>
<dependency>
<groupId>io.springfox</groupId>
<artifactId>springfox-swagger-ui</artifactId>
<version>2.4.0</version>
</dependency>
please let me know if worked for you.如果对你有用,请告诉我。
Resolved it, it was happening due to integration when Swagger + HATEOAS was used with Spring Boot 2.2.4.RELEASE解决了这个问题,当 Swagger + HATEOAS 与 Spring Boot 2.2.4.RELEASE 一起使用时,由于集成而发生了
package com.company.springbootworks.swagger;
import java.time.LocalDate;
import java.util.ArrayList;
import java.util.List;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.hateoas.client.LinkDiscoverer;
import org.springframework.hateoas.client.LinkDiscoverers;
import org.springframework.hateoas.mediatype.collectionjson.CollectionJsonLinkDiscoverer;
import org.springframework.http.ResponseEntity;
import org.springframework.plugin.core.SimplePluginRegistry;
import springfox.documentation.builders.ApiInfoBuilder;
import springfox.documentation.builders.PathSelectors;
import springfox.documentation.builders.RequestHandlerSelectors;
import springfox.documentation.service.ApiInfo;
import springfox.documentation.spi.DocumentationType;
import springfox.documentation.spring.web.plugins.Docket;
import springfox.documentation.swagger.web.DocExpansion;
import springfox.documentation.swagger.web.ModelRendering;
import springfox.documentation.swagger.web.OperationsSorter;
import springfox.documentation.swagger.web.TagsSorter;
import springfox.documentation.swagger.web.UiConfiguration;
import springfox.documentation.swagger.web.UiConfigurationBuilder;
import springfox.documentation.swagger2.annotations.EnableSwagger2;
@Configuration
@EnableSwagger2
public class SwaggerConfig {
@Bean
public LinkDiscoverers discoverers() {
List<LinkDiscoverer> plugins = new ArrayList<>();
plugins.add(new CollectionJsonLinkDiscoverer());
return new LinkDiscoverers(SimplePluginRegistry.create(plugins));
}
@Bean
public Docket eDesignApi(SwaggerConfigProperties swaggerConfigProperties) {
return new Docket(DocumentationType.SWAGGER_2).apiInfo(apiInfo(swaggerConfigProperties))
.enable(Boolean.valueOf(swaggerConfigProperties.getEnabled())).select()
.apis(RequestHandlerSelectors.any()).paths(PathSelectors.any()).build().pathMapping("/")
.directModelSubstitute(LocalDate.class, String.class).genericModelSubstitutes(ResponseEntity.class)
.useDefaultResponseMessages(Boolean.valueOf(swaggerConfigProperties.getUseDefaultResponseMessages()))
.enableUrlTemplating(Boolean.valueOf(swaggerConfigProperties.getEnableUrlTemplating()));
}
@Bean
UiConfiguration uiConfig(SwaggerConfigProperties swaggerConfigProperties) {
return UiConfigurationBuilder.builder().deepLinking(Boolean.valueOf(swaggerConfigProperties.getDeepLinking()))
.displayOperationId(Boolean.valueOf(swaggerConfigProperties.getDisplayOperationId()))
.defaultModelsExpandDepth(Integer.valueOf(swaggerConfigProperties.getDefaultModelsExpandDepth()))
.defaultModelExpandDepth(Integer.valueOf(swaggerConfigProperties.getDefaultModelExpandDepth()))
.defaultModelRendering(ModelRendering.EXAMPLE)
.displayRequestDuration(Boolean.valueOf(swaggerConfigProperties.getDisplayRequestDuration()))
.docExpansion(DocExpansion.NONE).filter(Boolean.valueOf(swaggerConfigProperties.getFilter()))
.maxDisplayedTags(Integer.valueOf(swaggerConfigProperties.getMaxDisplayedTags()))
.operationsSorter(OperationsSorter.ALPHA)
.showExtensions(Boolean.valueOf(swaggerConfigProperties.getShowExtensions()))
.tagsSorter(TagsSorter.ALPHA).supportedSubmitMethods(UiConfiguration.Constants.DEFAULT_SUBMIT_METHODS)
.validatorUrl(null).build();
}
private ApiInfo apiInfo(SwaggerConfigProperties swaggerConfigProperties) {
return new ApiInfoBuilder().title(swaggerConfigProperties.getTitle())
.description(swaggerConfigProperties.getDescription()).version(swaggerConfigProperties.getApiVersion())
.build();
}
}
and below are the swagger dependencies以下是 swagger 依赖项
<properties>
<java.version>1.8</java.version>
<swagger.version>2.9.2</swagger.version>
<swagger-annotations.version>1.5.21</swagger-annotations.version>
<swagger-models.version>1.5.21</swagger-models.version>
<spring-plugin.version>2.0.0.BUILD-SNAPSHOT</spring-plugin.version>
</properties>
<dependency>
<groupId>io.springfox</groupId>
<artifactId>springfox-swagger2</artifactId>
<version>${swagger.version}</version>
</dependency>
<dependency>
<groupId>io.springfox</groupId>
<artifactId>springfox-swagger-ui</artifactId>
<version>${swagger.version}</version>
</dependency>
<dependency>
<groupId>io.swagger</groupId>
<artifactId>swagger-annotations</artifactId>
<version>${swagger-annotations.version}</version>
</dependency>
<dependency>
<groupId>io.swagger</groupId>
<artifactId>swagger-models</artifactId>
<version>${swagger-models.version}</version>
</dependency>
If you want Swagger
, but can compromise with HATEOAS
, then just remove the HATEOAS dependency and add:如果您想要Swagger
,但可以与HATEOAS
妥协,那么只需删除 HATEOAS 依赖项并添加:
compile group: 'io.springfox', name: 'springfox-swagger-ui', version:'2.9.2'
compile group: 'io.springfox', name: 'springfox-swagger2', version: '2.9.2'
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.