swagger-ui没有找到HTTP请求的映射

时间:2017-04-21 14:41:31

标签: java spring spring-mvc swagger-ui springfox

我试图将Spring API文档和现有的Rest API作为Spring MVC项目(不是春季启动!)。

我的应用程序名为 api ,因此 http://localhost:9090/api 将成为根终结点。因为我使用spring-data-rest,在该URL上我可以看到所有暴露的存储库的json。到目前为止一切都很好。

我还可以访问招摇的JSON http://localhost:9090/api/v2/api-docs

问题

我无法访问 http://localhost:9090/api/swagger-ui.html 上的swagger-UI组件。它给了我

WARN  org.springframework.web.servlet.PageNotFound- No mapping found for HTTP request with URI [/api/swagger-ui.html] in DispatcherServlet with name 'dispatcher'

启动tomcat时检查spring日志我可以看到一些奇怪的东西

DEBUG org.springframework.beans.factory.support.DefaultListableBeanFactory- Finished creating instance of bean 'swaggerApiListingReader'
DEBUG org.springframework.web.servlet.handler.BeanNameUrlHandlerMapping- Rejected bean name 'swaggerConfig': no URL paths identified
DEBUG org.springframework.web.servlet.handler.BeanNameUrlHandlerMapping- Rejected bean name 'swagger2Controller': no URL paths identified
DEBUG org.springframework.web.servlet.handler.BeanNameUrlHandlerMapping- Rejected bean name 'swaggerMediaTypeReader': no URL paths identified
DEBUG org.springframework.web.servlet.handler.BeanNameUrlHandlerMapping- Rejected bean name 'swaggerOperationModelsProvider': no URL paths identified
DEBUG org.springframework.web.servlet.handler.BeanNameUrlHandlerMapping- Rejected bean name 'swaggerOperationResponseClassReader': no URL paths identified
DEBUG org.springframework.web.servlet.handler.BeanNameUrlHandlerMapping- Rejected bean name 'swaggerOperationTagsReader': no URL paths identified
DEBUG org.springframework.web.servlet.handler.BeanNameUrlHandlerMapping- Rejected bean name 'swaggerResponseMessageReader': no URL paths identified
DEBUG org.springframework.web.servlet.handler.BeanNameUrlHandlerMapping- Rejected bean name 'swaggerParameterDescriptionReader': no URL paths identified
DEBUG org.springframework.web.servlet.handler.BeanNameUrlHandlerMapping- Rejected bean name 'swaggerExpandedParameterBuilder': no URL paths identified
DEBUG org.springframework.web.servlet.handler.BeanNameUrlHandlerMapping- Rejected bean name 'swaggerApiListingReader': no URL paths identified
DEBUG org.springframework.web.servlet.handler.BeanNameUrlHandlerMapping- Rejected bean name 'swaggerProperties': no URL paths identified
DEBUG org.springframework.web.servlet.handler.BeanNameUrlHandlerMapping- Rejected bean name 'springfox.documentation.swagger.configuration.SwaggerCommonConfiguration': no URL paths identified
DEBUG org.springframework.web.servlet.handler.BeanNameUrlHandlerMapping- Rejected bean name 'springfox.documentation.swagger2.configuration.Swagger2DocumentationConfiguration': no URL paths identified
DEBUG org.springframework.web.servlet.handler.BeanNameUrlHandlerMapping- Rejected bean name 'swagger2Module': no URL paths identified

这似乎表明由于某种原因swaggerController没有与任何URL相关联,因此404错误。

这些是我使用

的版本
  <spring.version>4.2.8.RELEASE</spring.version>
  <spring-data.version>Gosling-SR4</spring-data.version>
  <spring-data-rest>2.4.6.RELEASE</spring-data-rest> 
   <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>
    <dependency>
        <groupId>io.springfox</groupId>
        <artifactId>springfox-data-rest</artifactId>
        <version>2.6.1</version>
    </dependency>

这是我的Java conf。值得指出的方法是 addResourceHandlers 从未执行过GETS

    @Configuration
    @EnableSwagger2
    @EnableWebMvc

  @Import({springfox.documentation.spring.data.rest.configuration.SpringDataRestConfiguration.class})
public class SwaggerConfig extends WebMvcConfigurerAdapter {
    @Bean
    public Docket api() {
        return new Docket(DocumentationType.SWAGGER_2)
                .select()
                .apis(RequestHandlerSelectors.any())
                .paths(PathSelectors.any())
                .build();
    }

    @Override
    public void addResourceHandlers(ResourceHandlerRegistry registry) {

        System.out.println("******************************Configuring swagger resource handler");
        registry.addResourceHandler("swagger-ui.html")
                .addResourceLocations("classpath:/META-INF/resources/");
        registry.addResourceHandler("/webjars/**")
                .addResourceLocations("classpath:/META-INF/resources/webjars/");
    }
}

有什么建议吗?简而言之,swagger-ui不起作用。

13 个答案:

答案 0 :(得分:15)

此解决方案由this answer

提供@oksett礼貌

创建一个扩展WebMvcConfigurerAdapter的配置类,并覆盖以下方法:

如果使用Spring 5,而不是扩展WebMvcConfigurerAdapter实现WebMvcConfigurer

@Override
public void addViewControllers(ViewControllerRegistry registry) {
    registry.addRedirectViewController("/api/v2/api-docs", "/v2/api-docs");
    registry.addRedirectViewController("/api/swagger-resources/configuration/ui", "/swagger-resources/configuration/ui");
    registry.addRedirectViewController("/api/swagger-resources/configuration/security", "/swagger-resources/configuration/security");
    registry.addRedirectViewController("/api/swagger-resources", "/swagger-resources");
}

@Override
public void addResourceHandlers(ResourceHandlerRegistry registry) {
    registry.addResourceHandler("/api/swagger-ui.html**").addResourceLocations("classpath:/META-INF/resources/swagger-ui.html");
    registry.addResourceHandler("/api/webjars/**").addResourceLocations("classpath:/META-INF/resources/webjars/");
}

在您的情况下,您需要向addViewControllers添加SwaggerConfig并将其付诸实施。另请注意addResourceHandlers方法中的更改,以便将/api添加到救援处理程序位置。

您现在应该可以访问我的swagger-ui.html @ http://localhost:9090/api/swagger-ui.html

答案 1 :(得分:5)

以下是有关如何使用swagger文档和可运行的UI配置spring boot的完整代码。

pom.xml

<!-- Spring boot version is 2.0.3.RELEASE-->

<dependencies>
  <!-- Swagger 2 Doc Dependency -->
  <dependency>
      <groupId>io.springfox</groupId>
      <artifactId>springfox-swagger2</artifactId>
      <version>2.9.2</version>
  </dependency>

  <!-- Swagger 2 UI -->
  <dependency>
      <groupId>io.springfox</groupId>
      <artifactId>springfox-swagger-ui</artifactId>
      <version>2.9.2</version>
  </dependency>
</dependencies>

SwaggerDocConfig.java

package com.example.springbootswagger.config;

import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Import;
import org.springframework.context.annotation.PropertySource;
import org.springframework.web.servlet.config.annotation.ResourceHandlerRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;
import springfox.bean.validators.configuration.BeanValidatorPluginsConfiguration;
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.swagger2.annotations.EnableSwagger2;

@Configuration
@EnableSwagger2
public class SwaggerDocConfig implements WebMvcConfigurer {

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

    @Bean
    public Docket apiDocket() {

        return new Docket(DocumentationType.SWAGGER_2)
                .apiInfo(getApiInfo())
                .select()
                .apis(RequestHandlerSelectors.basePackage("com.example.springbootswagger.controller"))
                .paths(PathSelectors.any())
                .build();
    }

    private ApiInfo getApiInfo() {

        return new ApiInfoBuilder()
                .title("Swagger API Doc")
                .description("More description about the API")
                .version("1.0.0")
                .build();
    }
}

答案 2 :(得分:1)

我们最终分别部署Swagger-UI客户端并通过Nginx提供服务。我们无法弄清楚它有什么问题,并且基于广泛的研究发现许多其他人有相同的难度,所以我们决定停止花时间尝试嵌入式方法。

答案 3 :(得分:1)

前段时间有类似的问题。我发现这是由自定义异常处理程序中的@EnableWebMvc注释引起的。

@ControllerAdvice
@RestController
@EnableWebMvc
public class CustomizedResponseEntityExceptionHandler extends ResponseEntityExceptionHandler {}

删除@EnableWebMvc对我来说很成功!

答案 4 :(得分:1)

为我工作

@Configuration
public class WebMvcConfig implements WebMvcConfigurer {
    @Override
    public void addResourceHandlers(ResourceHandlerRegistry registry) {
        registry.addResourceHandler("/static/**").addResourceLocations("classpath:/static/");
        registry.addResourceHandler("swagger-ui.html")
                .addResourceLocations("classpath:/META-INF/resources/");

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

答案 5 :(得分:1)

我已解决此实现问题:

import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
import org.springframework.security.core.annotation.AuthenticationPrincipal;

import com.google.common.base.Predicates;

import springfox.documentation.builders.PathSelectors;
import springfox.documentation.builders.RequestHandlerSelectors;
import springfox.documentation.spi.DocumentationType;
import springfox.documentation.spring.web.plugins.Docket;
import springfox.documentation.swagger2.annotations.EnableSwagger2;

@Configuration
@EnableSwagger2
public class SwaggerConfig extends WebSecurityConfigurerAdapter {
    public static String[] SWAGGER_URL_PATHS = new String[] { "/swagger-ui.html**", "/swagger-resources/**",
            "/v2/api-docs**", "/webjars/**" };

    @Override
    protected void configure(HttpSecurity http) throws Exception {
        http.csrf().disable();
        http.requestMatchers().antMatchers(SWAGGER_URL_PATHS).and().authorizeRequests().antMatchers(SWAGGER_URL_PATHS)
                .permitAll();
    }

    @Bean
    public Docket docket() {

        return new Docket(DocumentationType.SWAGGER_2).ignoredParameterTypes(AuthenticationPrincipal.class).select()
                .apis(Predicates.not(RequestHandlerSelectors.basePackage("org.springframework.boot")))
                .paths(PathSelectors.any()).build();
    }

}

P.S不要忘记在gradle文件中做到这一点

compile('org.springframework.boot:spring-boot-starter-security')

答案 6 :(得分:0)

有类似的问题和Dilips anwser工作。 更确切地说:

  1. 我的api-docs位置工作正常

  2. 我的swagger-ui.html正在呈现,但没有看到。在浏览器控制台中,我可以看到404 for / configuration / ui dir。

  3. 正确的目录是/ swagger-resources / configuration / ui所以我不得不进行重定向:

    registry.addRedirectViewController("/configuration/ui", "/swagger-resources/configuration/ui");
    

答案 7 :(得分:0)

这对我有用

Odoo Server Error
Traceback (most recent call last):
  File "/opt/odoo/odoo12/odoo/tools/cache.py", line 88, in lookup
    r = d[key]
  File "/opt/odoo/odoo12/odoo/tools/func.py", line 69, in wrapper
    return func(self, *args, **kwargs)
  File "/opt/odoo/odoo12/odoo/tools/lru.py", line 44, in __getitem__
    a = self.d[obj].me
KeyError: ('ir.model.data', <function IrModelData.xmlid_lookup at 0x7fe3b62f5400>, 'utilitypower.immobili')

During handling of the above exception, another exception occurred:

Traceback (most recent call last):
  File "/opt/odoo/odoo12/odoo/http.py", line 654, in _handle_exception
    return super(JsonRequest, self)._handle_exception(exception)
  File "/opt/odoo/odoo12/odoo/http.py", line 312, in _handle_exception
    raise pycompat.reraise(type(exception), exception, sys.exc_info()[2])
  File "/opt/odoo/odoo12/odoo/tools/pycompat.py", line 87, in reraise
    raise value
  File "/opt/odoo/odoo12/odoo/http.py", line 696, in dispatch
    result = self._call_function(**self.params)
  File "/opt/odoo/odoo12/odoo/http.py", line 344, in _call_function
    return checked_call(self.db, *args, **kwargs)
  File "/opt/odoo/odoo12/odoo/service/model.py", line 97, in wrapper
    return f(dbname, *args, **kwargs)
  File "/opt/odoo/odoo12/odoo/http.py", line 337, in checked_call
    result = self.endpoint(*a, **kw)
  File "/opt/odoo/odoo12/odoo/http.py", line 939, in __call__
    return self.method(*args, **kw)
  File "/opt/odoo/odoo12/odoo/http.py", line 517, in response_wrap
    response = f(*args, **kw)
  File "/opt/odoo/odoo12/addons/web/controllers/main.py", line 966, in call_button
    action = self._call_kw(model, method, args, {})
  File "/opt/odoo/odoo12/addons/web/controllers/main.py", line 954, in _call_kw
    return call_kw(request.env[model], method, args, kwargs)
  File "/opt/odoo/odoo12/odoo/api.py", line 749, in call_kw
    return _call_kw_multi(method, model, args, kwargs)
  File "/opt/odoo/odoo12/odoo/api.py", line 736, in _call_kw_multi
    result = method(recs, *args, **kwargs)
  File "/opt/odoo/odoo12-custom-addons/utility_power/models/utilitypower_ee_utenze.py", line 23, in action_view_form_modelname
    view = self.env.ref('utilitypower.utenze_ee')
  File "/opt/odoo/odoo12/odoo/api.py", line 854, in ref
    return self['ir.model.data'].xmlid_to_object(xml_id, raise_if_not_found=raise_if_not_found)
  File "/opt/odoo/odoo12/odoo/addons/base/models/ir_model.py", line 1396, in xmlid_to_object
    t = self.xmlid_to_res_model_res_id(xmlid, raise_if_not_found)
  File "/opt/odoo/odoo12/odoo/addons/base/models/ir_model.py", line 1380, in xmlid_to_res_model_res_id
    return self.xmlid_lookup(xmlid)[1:3]
  File "<decorator-gen-25>", line 2, in xmlid_lookup
  File "/opt/odoo/odoo12/odoo/tools/cache.py", line 93, in lookup
    value = d[key] = self.method(*args, **kwargs)
  File "/opt/odoo/odoo12/odoo/addons/base/models/ir_model.py", line 1369, in xmlid_lookup
    raise ValueError('External ID not found in the system: %s' % xmlid)
ValueError: External ID not found in the system: utilitypower.immobili

这是pom:

@Configuration
public class WebMvcConfig extends WebMvcConfigurationSupport{ 

@Override
public void addViewControllers(ViewControllerRegistry registry) {
  registry.addRedirectViewController("/configuration/ui", "/swagger-resources/configuration/ui");
}

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

答案 8 :(得分:0)

如果您使用的是Spring Boot,那就足够了:

<parent>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-parent</artifactId>
    <version>2.1.6.RELEASE</version>
    <relativePath />
</parent>



    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-web</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>

配置4大摇大摆:

@Configuration
@EnableSwagger2
public class SwaggerConfig {

    @Bean
    public Docket api() {
        return new Docket(DocumentationType.SWAGGER_2).select().apis(RequestHandlerSelectors.any()).paths(PathSelectors.any()).build();
    }
}

答案 9 :(得分:0)

截止到今天,新版本的Swagger可用:https://github.com/springfox/springfox

更好,更轻松的配置!我正在将Spring boot升级到2.3.1并向我的微服务中添加了招摇,在上述许多答案中提到的所有适当配置之后,都没有为swaggger-ui.html映射。一旦我使用了这个新版本,一切都很好!

答案 10 :(得分:0)

对于Spring Boot 2.x.x或Spring 5,在Swagger类配置中实现WebMvcConfigurer并添加以下注释:@Component@Configuration@EnableSwagger2。 看下面的实现:

@Component
@Configuration
@EnableSwagger2
public class SwaggerConfig implements WebMvcConfigurer {
    @Bean
    public Docket api(){
        return new Docket(DocumentationType.SWAGGER_2)
                .select()
                .apis(RequestHandlerSelectors.any())
                .paths(PathSelectors.any())
                .build()
                .apiInfo(getApiInfo());
    }

    private ApiInfo getApiInfo() {
        return new ApiInfoBuilder()
                .title("Custom Title")
                .description("Custom Description")
                .version("1.0.0")
                .build();
    }

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

}

如果您使用的是Spring 5或Spring Boot 2.x.x,那么swagger版本2.9.2是最兼容的

Maven依赖:

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

在以下位置签出swagger文档:http:// localhost:8080 / context-root / swagger-ui.html

答案 11 :(得分:0)

同样的事情发生在我身上,对我来说,从 3.0.0 版本到 2.9.2 版本很有效

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

答案 12 :(得分:0)

我正在使用 springfox 开放 API 3,这对我来说非常有效:

pom.xml

<dependency>
    <groupId>org.webjars</groupId>
    <artifactId>bootstrap</artifactId>
    <version>4.5.0</version>
</dependency>

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

        <dependency>
            <groupId>io.springfox</groupId>
            <artifactId>springfox-oas</artifactId>
            <version>3.0.0</version>
        </dependency>
   
        <dependency>
            <groupId>io.springfox</groupId>
            <artifactId>springfox-swagger2</artifactId>
            <version>3.0.0</version>

        </dependency>
       
        <dependency>
            <groupId>io.springfox</groupId>
            <artifactId>springfox-spring-web</artifactId>
            <version>3.0.0</version>
            
        </dependency>
        
        <dependency>
    <groupId>com.fasterxml.jackson.core</groupId>
    <artifactId>jackson-databind</artifactId>
    <version>2.12.2</version>
</dependency>

应用配置

@Configuration
@EnableWebMvc
@ComponentScan("com.swagger.sample.test")
@EnableOpenApi
public class AppConfiguration {
    
    
}

ServletInitializer

public class ServletInitializer extends AbstractAnnotationConfigDispatcherServletInitializer {
  @Override
  protected Class<?>[] getServletConfigClasses() {
    return new Class[] { AppConfiguration.class };
  }

  @Override
  protected String[] getServletMappings() {  
    return new String[] { "/" };
  }

  @Override
  protected Class<?>[] getRootConfigClasses() {
    return null;
  }

}

SpringConfig

@Component
public class SpringConfig implements WebMvcConfigurer {
    
    private static final Log LOGGER = LogFactory.getLog(ServletInitializer.class);

    
  @Override
  public void addResourceHandlers(ResourceHandlerRegistry registry) {       
      LOGGER.debug("[SpringConfig] addResourceHandlers");
        System.out.println("[SpringConfig] addResourcehandlers");
        registry. 
addResourceHandler("/swagger-ui/**")
.addResourceLocations("classpath:/META-INF/resources/webjars/springfox-swagger-ui/")
.resourceChain(false);
  }

  @Override
  public void addViewControllers(ViewControllerRegistry registry) {
              LOGGER.debug("[SpringConfig] addingViewControllers");
        System.out.println("[SpringConfig] addingViewControllers");
    registry.addViewController("/swagger-ui/")
        .setViewName("forward:" + "/swagger-ui/index.html");
  }
}

资源路径应该指向jar中index.html的位置 see this image