Spring boot 2.2.0 Spring проблема запуска HateOas

12

Я переместил свой проект с весенней загрузки 2.1.9 на 2.2.0. При запуске проекта сталкиваюсь с errorсообщениями ниже .

Что могло вызвать, я не использую hateoasв моем pom.xmlфайле либо.

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

<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>
Viyaan Jhiingade
источник
Используйте mvn dependency:treeи проверьте, вытягивает ли что-то еще Hateoas зависимость. IRC Если вы используете Spring Data REST, который зависит от Spring Hateoas.
М. Дейн
У меня такая же проблема при обновлении. Я знаю, откуда исходит зависимость, но я не смог найти решение.
mkeathley
Не могли бы вы направить меня сюда: stackoverflow.com/questions/60001241/… ?
Ash_P

Ответы:

13

У меня была эта проблема Swagger + HATEOASв моем spring-bootприложении.

Исправление приведено ниже (отредактируйте свой класс конфигурации 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));

    }
}
лимон
источник
Это не похоже на работу для меня , как _linksпревращаются linksи _embeddedпревращаются contentв ответ, поэтому большинство моего mvcMock тестов , контролирующих _linksне удается и API отличается от того , что предусмотрено из коробки с пружинной загрузкой starter- hateos
Керруба
У меня это тоже случилось. Вам нужно включить Hal + json
lemon
лимон не могли бы вы уточнить немного, пожалуйста? Я пытался использовать HalLinkDiscovererкласс вместо того, чтобы CollectionJsonLinkDiscovererне делать трюк, и все же мои тесты терпят неудачу, потому что ссылки отображаются как linksи нет _links, а также контент отображается как contentи не ожидалось_embedded
Kerruba
То, как я сделал это в своем файле конфигурации Java, @EnableHypermediaSupport(type=EnableHypermediaSupport.HypermediaType.HAL)вы должны включить org.springframework.hateoas.config.EnableHypermediaSupport. Не уверен, что это имеет значение, но у меня есть зависимость: spring-boot-starter-hateoas
лимон
@lemon Хороший ответ !! Это работает для весенних сапог 2.3.0 + hateoas + Swagger 2.9.2
Аниш Б.
2

Лучшее решение

Добавьте код ниже в классе SwaggerConfig

@Bean
public LinkDiscoverers discovers() {    
    List<LinkDiscoverer> plugins = new ArrayList<>();
    plugins.add(new CollectionJsonLinkDiscoverer());
    return new LinkDiscoverers(SimplePluginRegistry.create(plugins));[enter image description here][1]  
} 
Chanchal
источник
2

Для меня эта ссылка помогла: https://github.com/spring-projects/spring-hateoas/issues/731

В двух словах я добавил к своим зависимостям:

<dependency>
    <groupId>org.springframework.plugin</groupId>
    <artifactId>spring-plugin-core</artifactId>
    <version>2.0.0.RELEASE</version>
</dependency>
Александр Вайс
источник
Спасибо! Это сработало для меня. Кроме того, в этом руководстве есть ссылка на эту зависимость: baeldung.com/spring-hateoas-tutorial
neojal
1

попробуйте эту версию 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>
mudy
источник
1
Для меня это тоже ничего не изменило.
Rougou
Не могли бы вы помочь мне здесь: stackoverflow.com/questions/60001241/…
Ash_P
1

Проблема, с которой я столкнулся при использовании

<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>

с пружинным чванством

<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>

если вы посмотрите на зависимости Spring hateoas, есть зависимость spring-plugin-coreс версией2.0.0.RELEASE

<dependency>
    <groupId>org.springframework.plugin</groupId>
    <artifactId>spring-plugin-core</artifactId>
    <version>${spring-plugin.version}</version>
</dependency> 

но чванство использовать зависимость spring-plugin-coreс версией 1.2.0.RELEASE.

У Spring-Boot есть конфликт при создании bean-компонента, поэтому вам нужно унифицировать org.springframework.pluginверсию, чтобы Spring ее увидела. Если вы выберете 2.0.0.RELEASEswagger, бот сможет скомпилироваться,

так что версия 1.2.0.RELEASEбудет работать для обеих зависимостей, как

 <dependency>
    <groupId>org.springframework.plugin</groupId>
    <artifactId>spring-plugin-core</artifactId>
    <version>1.2.0.RELEASE</version>
</dependency> 

После этого вам нужен класс конфигурации для инициализации bean-компонентов swaggerи hateoasвот так:


@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();
    }
}
Ибрагим Аль Тамими
источник
0

Так что я на самом деле хотел поддержки hateoas и имел ту же проблему. Оказалось, что это произойдет, если у вас есть

<dependency>
  <groupId>org.springframework.hateoas</groupId>
  <artifactId>spring-hateoas</artifactId>
</dependency>

вместо

<dependency>
  <groupId>org.springframework.boot</groupId>
  <artifactId>spring-boot-starter-hateoas</artifactId>
</dependency>
mkeathley
источник
2
Также хочу отметить, что в настоящее время существует несовместимость с hateoas + swagger + spring boot 2.2.0. Вы можете запустить hateoas или чванство, но не оба. github.com/springfox/springfox/issues/2932
mkeathley
Я не использую hateoas, и не требую этого также. я даже пытался исключить зависимость hateoas от весеннего веб-стартера.
Viyaan Jhiingade
0

Если вы хотите 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'
KiniTap
источник
0

Решено, это происходило из-за интеграции, когда 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();
    }
}

и ниже - чванские зависимости

<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>
Нэвин
источник
Откуда вы получаете SwaggerConfigProperties?
Раджадилипколли
0

Я удалил эти зависимости как обходной путь и работал:

<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>

пожалуйста, дайте мне знать, если работал на вас.

Хосе Младший
источник
0

Для 2.1.3.RELEASEпользователей загрузочной версии Spring для hateoas + 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>
mrboieng
источник
0

Такая проблема возникает из-за новой функции Hateoas.

Если вы хотите решить эту проблему, просто вставьте следующую строку кодов в файл конфигурации swagger.

@Primary
@Bean
public LinkDiscoverers discoverers() {
    List<LinkDiscoverer> plugins = new ArrayList<>();
    plugins.add(new CollectionJsonLinkDiscoverer());
    return new LinkDiscoverers(SimplePluginRegistry.create(plugins));
}

Я думаю, что это решит вашу проблему так же, как и мою.

Сундар Гаутам
источник