Why HATEOAS starts creating issue for spring-boot version >= 2.2.x during startup with Swagger 2.x?
我将我的项目从 spring-boot 2.1.9 移动到 2.2.0。
在启动项目时,我面临以下
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 | 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] |
是什么导致了这个问题?
注意:我没有在我的
pom.xml
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 | <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> 0.8.1</assertj-swagger> <jacoco-version>0.8.4</jacoco-version> </properties> <dependencies> <dependency> <groupId>org.springframework.boot</groupId> spring-boot-starter-actuator</artifactId> </dependency> <dependency> <groupId>org.springframework.boot</groupId> spring-boot-starter-data-jpa</artifactId> </dependency> <dependency> <groupId>org.springframework.boot</groupId> spring-boot-starter-data-rest</artifactId> </dependency> <dependency> <groupId>org.springframework.boot</groupId> spring-boot-devtools</artifactId> <scope>runtime</scope> </dependency> <dependency> <groupId>org.springframework.boot</groupId> spring-boot-configuration-processor</artifactId> </dependency> <dependency> <groupId>org.projectlombok</groupId> lombok</artifactId> <optional>true</optional> </dependency> <dependency> <groupId>org.springframework.boot</groupId> spring-boot-starter-test</artifactId> <scope>test</scope> </dependency> <dependency> <groupId>io.springfox</groupId> springfox-swagger2</artifactId> <version>${swagger-springfox.version}</version> </dependency> <dependency> <groupId>io.springfox</groupId> springfox-swagger-ui</artifactId> <version>${swagger-springfox.version}</version> </dependency> <dependency> <groupId>io.springfox</groupId> springfox-spring-web</artifactId> <version>${swagger-springfox.version}</version> </dependency> <dependency> <groupId>io.springfox</groupId> springfox-core</artifactId> <version>${swagger-springfox.version}</version> </dependency> <dependency> <groupId>io.springfox</groupId> springfox-data-rest</artifactId> <version>${swagger-springfox.version}</version> </dependency> <dependency> <groupId>io.springfox</groupId> springfox-bean-validators</artifactId> <version>${swagger-springfox.version}</version> </dependency> |
我的
下面给出了修复(编辑你的 Swagger 配置类):
1 2 3 4 5 6 7 8 9 10 11 12 | @Configuration @EnableSwagger2 public class SwaggerConfiguration { @Bean public LinkDiscoverers discoverers() { List<LinkDiscoverer> plugins = new ArrayList<>(); plugins.add(new CollectionJsonLinkDiscoverer()); return new LinkDiscoverers(SimplePluginRegistry.create(plugins)); } } |
对我来说这个链接有帮助:https://github.com/spring-projects/spring-hateoas/issues/731
简而言之,我添加了我的依赖项:
1 2 3 4 5 | <dependency> <groupId>org.springframework.plugin</groupId> spring-plugin-core</artifactId> <version>2.0.0.RELEASE</version> </dependency> |
此类问题是由于 Hateoas 的一项新功能而发生的。
如果你想解决这个问题,只需在你的swagger配置文件中嵌入下面这行代码即可。
1 2 3 4 5 6 7 | @Primary @Bean public LinkDiscoverers discoverers() { List<LinkDiscoverer> plugins = new ArrayList<>(); plugins.add(new CollectionJsonLinkDiscoverer()); return new LinkDiscoverers(SimplePluginRegistry.create(plugins)); } |
我认为这会解决你的问题,因为它解决了我的问题。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 | 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> springfox-swagger2</artifactId> <version>3.0.0</version> </dependency> <dependency> <groupId>io.springfox</groupId> springfox-swagger-ui</artifactId> <version>3.0.0</version> </dependency> |
使用 3.0.0 版本后,swagger-ui 将无法工作,因此请使用以下依赖项和用户 /swagger-ui/ 而不是 /swagger-ui.html
1 2 3 4 5 | <dependency> <groupId>io.springfox</groupId> springfox-boot-starter</artifactId> <version>3.0.0</version> </dependency> |
我使用
时遇到的问题
1 2 3 4 5 6 7 8 9 10 11 12 13 | <dependency> <groupId>org.springframework.boot</groupId> spring-boot-dependencies</artifactId> <version>2.2.6.RELEASE</version> <type>pom</type> <scope>import</scope> </dependency> ..... ..... <dependency> <groupId>org.springframework.boot</groupId> spring-boot-starter-hateoas</artifactId> </dependency> |
用springfox招摇
1 2 3 4 5 6 7 8 9 10 | <dependency> <groupId>io.springfox</groupId> springfox-swagger2</artifactId> <version>2.9.2</version> </dependency> <dependency> <groupId>io.springfox</groupId> springfox-swagger-ui</artifactId> <version>2.9.2</version> </dependency> |
如果您查看 spring hateoas 依赖项,则存在对
的依赖项
1 2 3 4 5 | <dependency> <groupId>org.springframework.plugin</groupId> spring-plugin-core</artifactId> <version>${spring-plugin.version}</version> </dependency> |
但是大张旗鼓的依赖使用
spring-boot创建bean有冲突,需要统一
所以版本
1 2 3 4 5 | <dependency> <groupId>org.springframework.plugin</groupId> spring-plugin-core</artifactId> <version>1.2.0.RELEASE</version> </dependency> |
之后,您需要配置类来为
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 | @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","[email protected]"); return new ApiInfoBuilder() .title(""{ApplicationName}"") .description("API Description") .license("license") .version("1.0") .contact(contact) .licenseUrl("licenseURl") .build(); } } |
对于 Spring boot 版本
1 2 3 4 5 6 7 8 9 10 11 12 13 14 | <dependency> <groupId>org.springframework.boot</groupId> spring-boot-starter-hateoas</artifactId> </dependency> <dependency> <groupId>io.springfox</groupId> springfox-swagger2</artifactId> <version>2.9.2</version> </dependency> <dependency> <groupId>io.springfox</groupId> springfox-swagger-ui</artifactId> <version>2.9.2</version> </dependency> |
试试这个2.6.1版本,我已经用这个方法解决了
1 2 3 4 5 6 7 8 9 10 | <dependency> <groupId>io.springfox</groupId> springfox-swagger2</artifactId> <version>2.6.1</version> </dependency> <dependency> <groupId>io.springfox</groupId> springfox-swagger-ui</artifactId> <version>2.6.1</version> </dependency> |
我正在使用 springdoc-openapi,在遇到类似于这里提到的问题后:
1 2 3 4 5 6 7 8 9 10 11 | 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 |
我只是在我的 pom 文件中添加了这个依赖
1 2 3 4 5 | <dependency> <groupId>org.springframework.hateoas</groupId> spring-hateoas</artifactId> <version>1.1.1.RELEASE</version> </dependency> |
希望这可以帮助某人
最佳解决方案
在 SwaggerConfig 类中添加以下代码
1 2 3 4 5 6 | @Bean public LinkDiscoverers discovers() { List<LinkDiscoverer> plugins = new ArrayList<>(); plugins.add(new CollectionJsonLinkDiscoverer()); return new LinkDiscoverers(SimplePluginRegistry.create(plugins));[enter image description here][1] } |
作为亚历山大·魏?已经回答,
为了强制使用正确的
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 | <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> spring-plugin-core</artifactId> <version>${spring-plugin-core.version}</version> </dependency> <dependency> <groupId>io.springfox</groupId> springfox-boot-starter</artifactId> <version>${springfox.version}</version> </dependency> </dependencies> </dependencyManagement> <dependencies> <!-- API Documentation --> <dependency> <groupId>io.springfox</groupId> springfox-boot-starter</artifactId> </dependency> </dependencies> |
我收到错误
"在类路径资源 [org/springframework/hateoas/mediatype/hal/HalMediaTypeConfiguration.class] 中定义名称为 'halLinkDisocoverer' 的 bean 创建错误"..
在构建超媒体驱动的 RESTful Web 服务时
删除这个依赖
1 2 3 4 5 | <dependency> <groupId>com.jayway.jsonpath</groupId> json-path</artifactId> <scope>test</scope> </dependency> |
解决了我的问题。
查看此链接了解更多详情
为什么我收到错误工厂方法"halLinkDisocoverer"在 springboot 中引发异常?
您可以像这样更改版本:
1 2 3 4 5 6 7 8 9 10 | <dependency> <groupId>io.springfox</groupId> springfox-swagger2</artifactId> <version>3.0.0</version> </dependency> <dependency> <groupId>io.springfox</groupId> springfox-swagger-ui</artifactId> <version>2.8.0</version> </dependency> |
我正在使用 Spring Boot 2.4.1。但是在启动 Spring Boot 应用程序时看不到 Swagger 端点日志。
所以我实际上想要 hatoas 支持并且遇到了同样的问题。如果你有
就会发生这种情况
1 2 3 4 | <dependency> <groupId>org.springframework.hateoas</groupId> spring-hateoas</artifactId> </dependency> |
而不是
1 2 3 4 | <dependency> <groupId>org.springframework.boot</groupId> spring-boot-starter-hateoas</artifactId> </dependency> |
已解决,当 Swagger HATEOAS 与 Spring Boot 2.2.4.RELEASE 一起使用时,由于集成而发生此问题。RELEASE
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 | 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(); } } |
及以下是swagger依赖
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 | <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> springfox-swagger2</artifactId> <version>${swagger.version}</version> </dependency> <dependency> <groupId>io.springfox</groupId> springfox-swagger-ui</artifactId> <version>${swagger.version}</version> </dependency> <dependency> <groupId>io.swagger</groupId> swagger-annotations</artifactId> <version>${swagger-annotations.version}</version> </dependency> <dependency> <groupId>io.swagger</groupId> swagger-models</artifactId> <version>${swagger-models.version}</version> </dependency> |
我已经删除了这些依赖项作为解决方法并工作了:
1 2 3 4 5 6 7 8 9 10 11 | <dependency> <groupId>io.springfox</groupId> springfox-swagger2</artifactId> <version>2.4.0</version> </dependency> <dependency> <groupId>io.springfox</groupId> springfox-swagger-ui</artifactId> <version>2.4.0</version> </dependency> |
如果对你有用,请告诉我。
如果你想要
1 2 | compile group: 'io.springfox', name: 'springfox-swagger-ui', version:'2.9.2' compile group: 'io.springfox', name: 'springfox-swagger2', version: '2.9.2' |