web-dev-qa-db-fra.com

Impossible de faire apparaître swagger-ui à partir de l'application Spring-Boot

J'ai une application de démarrage de printemps que j'utilise avec un serveur Tomcat intégré. Je réussis partiellement à intégrer springfox-swagger à l'application. Si je fais un / v2/api-docs, je peux voir toute la documentation de toutes les api de la webapp. Cependant, lorsque j'essaie d'accéder à la même chose à partir de l'interface utilisateur, cela ne fonctionne pas. Voici les résultats détaillés.

Sortie de - localhost: 8080/api/swagger-resources

[ {
  "name" : "default",
  "location" : "/v2/api-docs",
  "swaggerVersion" : "2.0"
} ]

Sortie de - localhost: 8080/api/v2/api-docs

I get valid results. I can confirm that and the output is too large to paste here

Mais lorsque j'essaie d'accéder à swagger-ui, cela ne fonctionne pas. Vous trouverez ci-dessous les différentes URL invoquées pour accéder à swagger-ui.

http://localhost:8080/swagger-ui.html - UI is loading, but no documentation of API's is present
http://localhost:8080/api/swagger-ui.html  - 404 Not Found
http://localhost:8080/springfox - 404 Not Found
http://localhost:8080/api/springfox - 404 Not Found

Ci-dessous ma classe SwaggerConfig.Java

package com.vmware.vrack.lcm;

import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
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.UiConfiguration;
import springfox.documentation.swagger2.annotations.EnableSwagger2;

import static springfox.documentation.builders.PathSelectors.regex;

@Configuration
@EnableSwagger2
public class SwaggerConfig {

    @Bean
    public Docket api() {
        return new Docket(DocumentationType.SWAGGER_2)
                .select()
                .apis(RequestHandlerSelectors.any())
                .paths(regex("/.*"))
                .build()
                .apiInfo(apiInfo());
    }

    private ApiInfo apiInfo() {
        ApiInfo apiInfo = new ApiInfo(
                "My Project's REST API",
                "This is a description of your API.",
                "version-1",
                "API TOS",
                "[email protected]",
                "API License",
                "API License URL"
        );
        return apiInfo;
    }

}

Ci-dessous les dépendances swagger que j'utilise 

<dependency>
   <groupId>io.springfox</groupId>
   <artifactId>springfox-swagger2</artifactId>
   <version>2.2.2</version>
</dependency>
<dependency>
   <groupId>io.springfox</groupId>
   <artifactId>springfox-swagger-ui</artifactId>
   <version>2.2.2</version>
</dependency>

Vous trouverez ci-dessous le fichier webconfig du convertisseur de messages.

@Configuration
@EnableWebMvc
public class WebConfig extends WebMvcConfigurerAdapter {

    @Override
    public void configureMessageConverters(List<HttpMessageConverter<?>> converters) {
        converters.add(jackson2Converter());
    }

    @Bean
    public MappingJackson2HttpMessageConverter jackson2Converter() {
        MappingJackson2HttpMessageConverter converter = new MappingJackson2HttpMessageConverter();
        converter.setObjectMapper(objectMapper());
        return converter;
    }

    @Bean
    public ObjectMapper objectMapper() {
        ObjectMapper objectMapper = new ObjectMapper();
        objectMapper.enable(SerializationFeature.INDENT_OUTPUT);
        return objectMapper;
    }
}

Le lien ci-dessous indique que @EnableWebMvc ne doit pas être utilisé dans une application Web spring-boot et que l'utilisation de l'annotation peut entraîner des problèmes pour amener swagger-ui. Mais, si je n'utilise pas l'annotation, l'application Web n'apparaît pas (j'ai collé la trace d'erreur de pile ci-dessous)

http://springfox.github.io/springfox/docs/current/#configuring-the-objectmapper

Trace d'erreur lorsque je n'utilise pas l'annotation @EnableWebMvc

org.springframework.beans.factory.UnsatisfiedDependencyException: Error creating bean with name 'documentationPluginsBootstrapper' defined in URL [jar:file:/Users/ngorijala/.m2/repository/io/springfox/springfox-spring-web/2.2.2/springfox-spring-web-2.2.2.jar!/springfox/documentation/spring/web/plugins/DocumentationPluginsBootstrapper.class]: Unsatisfied dependency expressed through constructor argument with index 1 of type [springfox.documentation.spi.service.RequestHandlerProvider]: : Error creating bean with name 'webMvcRequestHandlerProvider' defined in URL [jar:file:/Users/ngorijala/.m2/repository/io/springfox/springfox-spring-web/2.2.2/springfox-spring-web-2.2.2.jar!/springfox/documentation/spring/web/plugins/WebMvcRequestHandlerProvider.class]: Unsatisfied dependency expressed through constructor argument with index 0 of type [Java.util.List]: : No qualifying bean of type [org.springframework.web.servlet.mvc.method.RequestMappingInfoHandlerMapping] found for dependency [collection of org.springframework.web.servlet.mvc.method.RequestMappingInfoHandlerMapping]: expected at least 1 bean which qualifies as autowire candidate for this dependency. Dependency annotations: {}; nested exception is org.springframework.beans.factory.NoSuchBeanDefinitionException: No qualifying bean of type [org.springframework.web.servlet.mvc.method.RequestMappingInfoHandlerMapping] found for dependency [collection of org.springframework.web.servlet.mvc.method.RequestMappingInfoHandlerMapping]: expected at least 1 bean which qualifies as autowire candidate for this dependency. Dependency annotations: {}; nested exception is org.springframework.beans.factory.UnsatisfiedDependencyException: Error creating bean with name 'webMvcRequestHandlerProvider' defined in URL [jar:file:/Users/ngorijala/.m2/repository/io/springfox/springfox-spring-web/2.2.2/springfox-spring-web-2.2.2.jar!/springfox/documentation/spring/web/plugins/WebMvcRequestHandlerProvider.class]: Unsatisfied dependency expressed through constructor argument with index 0 of type [Java.util.List]: : No qualifying bean of type [org.springframework.web.servlet.mvc.method.RequestMappingInfoHandlerMapping] found for dependency [collection of org.springframework.web.servlet.mvc.method.RequestMappingInfoHandlerMapping]: expected at least 1 bean which qualifies as autowire candidate for this dependency. Dependency annotations: {}; nested exception is org.springframework.beans.factory.NoSuchBeanDefinitionException: No qualifying bean of type [org.springframework.web.servlet.mvc.method.RequestMappingInfoHandlerMapping] found for dependency [collection of org.springframework.web.servlet.mvc.method.RequestMappingInfoHandlerMapping]: expected at least 1 bean which qualifies as autowire candidate for this dependency. Dependency annotations: {}
    at org.springframework.beans.factory.support.ConstructorResolver.createArgumentArray(ConstructorResolver.Java:749)
    at org.springframework.beans.factory.support.ConstructorResolver.autowireConstructor(ConstructorResolver.Java:185)
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.autowireConstructor(AbstractAutowireCapableBeanFactory.Java:1139)
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBeanInstance(AbstractAutowireCapableBeanFactory.Java:1042)
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.Java:504)
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.Java:476)
    at org.springframework.beans.factory.support.AbstractBeanFactory$1.getObject(AbstractBeanFactory.Java:303)
    at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.Java:230)
    at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.Java:299)
    at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.Java:194)
    at org.springframework.beans.factory.support.DefaultListableBeanFactory.preInstantiateSingletons(DefaultListableBeanFactory.Java:755)
    at org.springframework.context.support.AbstractApplicationContext.finishBeanFactoryInitialization(AbstractApplicationContext.Java:757)
    at org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.Java:480)
    at org.springframework.web.context.ContextLoader.configureAndRefreshWebApplicationContext(ContextLoader.Java:403)
    at org.springframework.web.context.ContextLoader.initWebApplicationContext(ContextLoader.Java:306)
    at org.springframework.web.context.ContextLoaderListener.contextInitialized(ContextLoaderListener.Java:106)
    at org.Eclipse.jetty.server.handler.ContextHandler.callContextInitialized(ContextHandler.Java:799)
    at org.Eclipse.jetty.servlet.ServletContextHandler.callContextInitialized(ServletContextHandler.Java:499)
    at org.Eclipse.jetty.server.handler.ContextHandler.startContext(ContextHandler.Java:790)
    at org.Eclipse.jetty.servlet.ServletContextHandler.startContext(ServletContextHandler.Java:337)
    at org.Eclipse.jetty.webapp.WebAppContext.startWebapp(WebAppContext.Java:1343)
    at org.Eclipse.jetty.maven.plugin.JettyWebAppContext.startWebapp(JettyWebAppContext.Java:296)
    at org.Eclipse.jetty.webapp.WebAppContext.startContext(WebAppContext.Java:1336)
    at org.Eclipse.jetty.server.handler.ContextHandler.doStart(ContextHandler.Java:742)
    at org.Eclipse.jetty.webapp.WebAppContext.doStart(WebAppContext.Java:499)
    at org.Eclipse.jetty.maven.plugin.JettyWebAppContext.doStart(JettyWebAppContext.Java:365)
    at org.Eclipse.jetty.util.component.AbstractLifeCycle.start(AbstractLifeCycle.Java:68)
    at org.Eclipse.jetty.util.component.ContainerLifeCycle.start(ContainerLifeCycle.Java:132)
    at org.Eclipse.jetty.util.component.ContainerLifeCycle.doStart(ContainerLifeCycle.Java:114)
    at org.Eclipse.jetty.server.handler.AbstractHandler.doStart(AbstractHandler.Java:61)
    at org.Eclipse.jetty.server.handler.ContextHandlerCollection.doStart(ContextHandlerCollection.Java:163)

J'ai le sentiment qu'il me manque quelque chose de trivial. Quelqu'un peut-il s'il vous plaît jeter un oeil et laissez-moi savoir ce que je manque. Merci d'avance.!!

11
Naveen Chandra

Si vous souhaitez conserver les annotations @EnableWebMvc de quelque manière que ce soit, vous devez ajouter les éléments 

  @Override
    public void addResourceHandlers(ResourceHandlerRegistry registry) {

            registry.addResourceHandler("swagger-ui.html")
                    .addResourceLocations("classpath:/META-INF/resources/");

            registry.addResourceHandler("/webjars/**")
                    .addResourceLocations("classpath:/META-INF/resources/webjars/");

    }
15
maruf571

springfox-swagger-ui est un fichier jar Web. Vous devez donc configurer des gestionnaires de ressources pour informer le servlet de répartition du type et de la ressource à utiliser lorsque vous demandez ../swagger-ui.html. Habituellement, dans une application Spring-Boot, auto-configuration se charge de la configurer pour vous. La raison pour laquelle il ne se charge pas dans votre cas, c'est parce que vous avez signalé à spring-boot que l'application sera configurée manuellement via la combinaison WebMvcConfigurerAdapter/@EnableWebMvc

Vous devriez pouvoir placer l'annotation @SpringBootApplication sur votre configuration de ressort principale et vous débarrasser de la classe WebConfig au complet. 

Puisque votre WebConfig n'ajoute aucune valeur autre que celle de s'assurer que le JSON est en retrait, je suggérerais de le supprimer complètement et de le remplacer par un Jackson2ObjectMapperBuilder bean.

Pour des exemples sur la façon de faire la même chose dans spring-mvc/spring-boot, etc., jetez un coup d'œil au projet springfox-demos . En particulier, regardez SpringConfig pour savoir comment configurer manuellement les gestionnaires de ressources.

8
Dilip Krishnan

J'ai rencontré ce problème auparavant et le problème se trouvait dans la ligne ci-dessous dans application.properties

spring.resources.add-mappings = false

supprimez-le ou changez sa valeur en true

1
Bahgat Mashaly

Cela a fonctionné pour moi, quand je ne remplace pas le modèle de chemin statique.

Dans l’application de démarrage du printemps, il suffit d’éviter " spring.mvc.static-path-pattern " du fichier de propriétés et swagger-ui fonctionnera correctement.

0
VIrtual Host