无法从spring-boot应用程序中启动swagger-ui

25

我有一个使用内嵌Tomcat服务器运行的Spring Boot应用程序。我已部分成功地将Springfox Swagger集成到应用程序中。如果我执行/v2/api-docs,我可以看到Web应用程序中所有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>

以下是消息转换器的Web配置文件

@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;
    }
}
以下链接指出,在Spring Boot Web应用程序中不应使用@EnableWebMvc注解,使用该注解可能会导致无法启动swagger-ui。但是,如果我不使用该注解,则Web应用程序将无法启动(我已经粘贴了错误堆栈跟踪信息)。

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)

我有一种感觉,似乎错过了一些微不足道的东西。请问有人可以看一下并告诉我错过了什么吗?谢谢!

6个回答

28
如果您想保留@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/");

    }

3
感谢解决我的问题,给你点个赞。请注意,这种方法要放在扩展WebMvcConfigurerAdapter类的内部。 - idungotnosn
在添加这些值的时候,请确保您从这里复制粘贴,因为如果您错过了末尾的 "/",您将会收到404错误。 - damndemon
错误:(108,-1)方法未覆盖或实现超类型的方法 - PUG

18

springfox-swagger-ui是Web JAR,需要设置资源处理程序来通知调度servlet如何以及哪些资源在请求../swagger-ui.html时提供。通常在Spring Boot应用程序中,自动配置会为您处理它。如果在你的情况下没有加载成功,那么可能是因为您已经通过WebMvcConfigurerAdapter/@EnableWebMvc组合向Spring Boot指示应用程序将进行手动配置。

您应该能够将@SpringBootApplication注解放置在主Spring配置上,并且完全删除WebConfig类。

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

有关在Spring MVC / Spring Boot等中执行相同操作的示例,请查看springfox-demos项目。特别是查看SpringConfig,以了解如何手动配置资源处理程序。


已删除@EnableWebMvc,/swagger-ui.html现在可用。谢谢! - Dmitri Algazin

5

我以前遇到过这个问题,问题出在 application.properties 文件中的以下行:

spring.resources.add-mappings=false

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


1

当我没有覆盖静态路径模式时,它对我起作用。

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


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

0
对我来说,问题出在Swagger API和Spring Boot框架的版本上。 我使用的是Spring Boot最新版本2.6.0和Swagger 3.0.0。
我切换到了我的Parent Version中的Spring Boot 2.4.0。即使您的项目中有devtools,请手动进行一次maven更新项目,然后运行它。
访问URL:your-base-url/swagger-ui/

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接