无法从 spring-boot 应用程序中调出 swagger-ui

Posted

技术标签:

【中文标题】无法从 spring-boot 应用程序中调出 swagger-ui【英文标题】:Unable to bring up swagger-ui from spring-boot application 【发布时间】:2015-11-18 13:58:03 【问题描述】:

我有一个使用嵌入式 tomcat 服务器运行的 spring boot 应用程序。我在将 springfox-swagger 与应用程序集成方面取得了部分成功。如果我执行 /v2/api-docs ,我可以在 webapp 中看到所有 api 的所有文档。但是,当我尝试从 UI 访问相同的内容时,它不起作用。以下是详细结果。

输出 - localhost:8080/api/swagger-resources

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

输出 - localhost:8080/api/v2/api-docs

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

但是当我尝试访问 swagger-ui 时,它不起作用。下面是我用来访问 swagger-ui 的不同 URL。

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

下面是我的 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",
                "me@wherever.com",
                "API License",
                "API License URL"
        );
        return apiInfo;
    


以下是我正在使用的 swagger 依赖项

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

下面是消息转换器的webconfig文件

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

下面的链接说 @EnableWebMvc 不应在 spring-boot webapp 中使用,并且使用注释可能会导致启动 swagger-ui 时出现问题。但是,如果我不使用注释,web-app 就不会出现(我在下面粘贴了错误堆栈跟踪)

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

当我不使用 @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)

我有一种感觉,我错过了一些微不足道的事情。有人可以看看,让我知道我错过了什么。?提前致谢!!

【问题讨论】:

【参考方案1】:

如果你想以任何方式保留@EnableWebMvc注解,你必须添加以下内容

  @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/");

    

【讨论】:

+1 用于解决我的问题。谢谢你。另请注意,此方法位于扩展 WebMvcConfigurerAdapter 的类内部。 添加这些值时,请确保从此处复制粘贴它们,因为如果您错过最后的“/”,您将收到 404 错误。 错误:(108, -1) 方法没有覆盖或实现超类型中的方法【参考方案2】:

springfox-swagger-ui 是一个 web jar,它要求您设置资源处理程序,以便在您请求 ../swagger-ui.html 时通知调度 servlet 如何以及提供哪些资源。通常在 spring-boot 应用程序中 auto-configuration 会为您设置它。在您的情况下它没有加载的原因是因为您已经向 spring-boot 发出信号,表明该应用程序将通过 WebMvcConfigurerAdapter/@EnableWebMvc 组合手动配置。

您应该能够将@SpringBootApplication 注释放在您的主要弹簧配置上,并完全摆脱WebConfig 类。

由于您的 WebConfig 除了确保 JSON 缩进之外没有添加任何值,我建议将其全部删除并用 Jackson2ObjectMapperBuilder bean 替换它。

有关如何在 spring-mvc/spring-boot 等中执行相同操作的示例,请查看springfox-demos project。尤其是查看SpringConfig,了解如何手动配置资源处理程序。

【讨论】:

删除了 @EnableWebMvc 并且 /swagger-ui.html 可用。谢谢!【参考方案3】:

我之前也遇到过这个问题,问题在application.properties的下面一行:

spring.resources.add-mappings=false

删除它或将其值更改为 true。

【讨论】:

【参考方案4】:

当我试图覆盖静态路径模式时,它对我有用。

在 Spring Boot 应用程序中,只需从属性文件中避免“spring.mvc.static-path-pattern”,swagger-ui 就可以正常工作。

【讨论】:

【参考方案5】:

在我的情况下,我在属性文件中删除了spring.resources.static-locations,它可以工作。

【讨论】:

【参考方案6】:

对我来说,问题在于 Swagger API 和 Spring Boot Framework 的版本。 我正在使用带有 Swagger 3.0.0 的 Spring Boot 最新版本 2.6.0

我在父版本中切换到 Spring Boot 2.4.0。即使您的项目中有 devtools,也请执行一个手动 maven 更新项目,然后运行它。

点击网址:your-base-url/swagger-ui/

【讨论】:

以上是关于无法从 spring-boot 应用程序中调出 swagger-ui的主要内容,如果未能解决你的问题,请参考以下文章

无法在 spring-boot 应用程序中从 Consul 读取配置

示例 keycloak spring-boot 应用程序无法找到 bean KeycloakSpringBootConfigResolver

Spring-Boot 多模块无法从另一个模块读取属性文件

无法在 IntelliJ Idea 中启动 spring-boot 应用程序

无法将我的spring-boot应用程序与mongodb云图集连接起来

为啥 spring-boot 应用程序无法在 AWS 中运行,但在本地运行良好?