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]

치어 리더

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

mvn dependency:tree다른 것이 Hateoas 의존성을 끌어 당기고 있는지 확인하고 사용하십시오 . IRC Spring Hateoas에 의존하는 Spring Data REST를 사용하는 경우.
M. Deinum

업그레이드와 동일한 문제가 있습니다. 종속성이 어디에서 왔는지 알지만 해결책을 찾지 못했습니다.
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 봄 부팅 - 도입 - 함께 상자 밖으로 제공 무슨 다른됩니다 hateos
Kerruba

나도 이런 일이 있었다.
lemon

레몬 좀 해주세요 나는의 사용을 시도한 HalLinkDiscoverer대신 클래스 CollectionJsonLinkDiscoverer트릭을하지 않았고 여전히 내 테스트 링크로 렌더링되기 때문에 실패 links가 아니라 _links내용으로 렌더링뿐만 아니라, content예상하지_embedded
Kerruba

내 구성 Java 파일에서 수행 한 방식 @EnableHypermediaSupport(type=EnableHypermediaSupport.HypermediaType.HAL)은 포함해야했습니다 org.springframework.hateoas.config.EnableHypermediaSupport. 그것이 중요한지 확실하지 않지만 의존성이 있습니다 : spring-boot-starter-hateoas
lemon

@lemon 좋은 답변 !! 이것은 spring-boot 2.3.0 + hateoas + Swagger 2.9.2
Anish B에서 작동합니다.

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

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>

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>

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>

당신이 봄의 hateoas 의존성을 살펴보면 spring-plugin-coreversion과 의 의존성이 있습니다.2.0.0.RELEASE

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

그러나 swagger 종속성 spring-plugin-core은 version과 함께 사용 1.2.0.RELEASE합니다.

spring-boot는 bean 생성과 충돌하므로 org.springframework.pluginspring을 볼 수 있도록 버전을 통합해야 합니다. 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> 

그런 다음 다음 swaggerhateoas같은 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();
    }
}

0

그래서 실제로 증오 지원을 원했고 같은 문제가있었습니다. 이 경우에 발생합니다

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

대신에

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

2
또한 hateoas + swagger + spring boot 2.2.0과 현재 호환되지 않는다는 것을 지적하고 싶습니다. hateoas 또는 swagger를 실행할 수 있지만 둘 다 실행할 수는 없습니다. github.com/springfox/springfox/issues/2932
mkeathley

증오심을 사용하지 않으며, 필요하지도 않습니다. 나는 심지어 스프링 웹 스타터에서 증오 의존성을 배제하려고 시도했다.
Viyaan Jhiingade

0

을 원 Swagger하지만로 타협 할 수 있으면 HATEOASHATEOAS 종속성을 제거하고 다음을 추가하십시오.

compile group: 'io.springfox', name: 'springfox-swagger-ui', version:'2.9.2'  
compile group: 'io.springfox', name: 'springfox-swagger2', version: '2.9.2'

0

Swagger + HATEOAS가 Spring Boot 2.2.4와 함께 사용되었을 때 통합으로 인해 발생하는 문제가 해결되었습니다.

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 의존성입니다.

<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를 얻습니까?
rajadilipkolli

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

Spring 부트 버전 2.1.3.RELEASE사용자의 경우 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>
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.