swagger-ui No mapping found for HTTP request
Asked Answered
G

16

23

I'm trying to document and existing Rest API a Spring MVC project (NOT spring boot!).

My application is called api so http://localhost:9090/api would be the root endpoint. Because I'm using spring-data-rest, on that URL I can see the json of all my exposed repositories. So far so good.

I can also access the swagger JSON http://localhost:9090/api/v2/api-docs

The problem

I can't access the swagger-UI component on http://localhost:9090/api/swagger-ui.html . It gives me

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

Checking the spring logs when starting tomcat I can see something weird

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

That seems to indicate the for some reason swaggerController is not associated to any URL, hence the 404 error.

These are the version I'm working with

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

This is my Java conf. Worth pointing out that the method addResourceHandlers NEVER GETS executed

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

Any suggestions? In short, swagger-ui does not work.

Garbo answered 21/4, 2017 at 14:41 Comment(0)
H
32

This solution is courtesy this answer by @oksett

Create a configuration class, which extends WebMvcConfigurerAdapter and override the following methods:

If Using Spring 5, instead of extends WebMvcConfigurerAdapter implements 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/");
}

In your case you need to add and implementation of addViewControllers to SwaggerConfig. Also note the changes in the addResourceHandlers method to prepend /api to the the rescue handler location.

You should now be able to access into my swagger-ui.html @ http://localhost:9090/api/swagger-ui.html

Harshman answered 21/4, 2017 at 14:56 Comment(6)
Thanks. No luck though. I can still see in spring logs BeanNameUrlHandlerMapping- Rejected bean ...: no URL paths identified for all swaggerBeans (swaggerConfig, swagger2Controller, swaggerMediaTypeReader, etc). Also the link from which you took the solution is spring boot . Any other idea?Garbo
The first thing I need to make sure is that the configuration actually executes when loading. Both addViewControllers and addResourceHandlers are never executed which I believe is the root cause....Garbo
Its a spring mvc solution, boot is a super set. Secondly about the rejected bean, message, its a debug message so it might be a red-herring you're chasing. If it were significant you'd not see anything in the /v2/apidocs endpoint because one of the beans rejected is swagger2Controller. Another thing to try is to remove the @EnableWebMvc.Harshman
got you re spring boot and yeah it's DEBUG so it should not matter. What is the bit of configuration in Spring that triggers addViewControllers and * addResourceHandlers* ? That has not yet happened neither with my example or with your suggestion.Garbo
@filipe did this answer your question?Harshman
No Sr. Thanks for asking! The weirdest thing is that my colleague can access localhost:9090/api/swagger-ui.html with no problems...EXACTLY the same code base so I'm lost with this one. The only difference is that I'm running everything on a Mac and my colleague is in Linux so I'm now trying to run tomcat in a docker container (linux) and see what happens...if you do have any other suggestion please let us know.Garbo
N
20

The following is a complete code on how to configure spring boot with swagger doc and working UI.

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();
    }
}
Nanoid answered 15/11, 2018 at 10:24 Comment(1)
FYI, I used the exact above config, and I get the same error: No mapping found for HTTP request with URI [/swagger-resources/configuration/ui]. There is something missing.Domeniga
D
15

Had a similar problem a while ago. I found out it was caused by @EnableWebMvc annotation in my custom Exception Handler.

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

Removing @EnableWebMvc did the trick for me!!

Ditter answered 11/4, 2019 at 9:49 Comment(1)
Is there any option without removing @EnableWebMvc? I need this annotation for ContentNegotiationJiva
R
8

This work for me

@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/");    
   }
}
Rosenfeld answered 21/5, 2019 at 6:6 Comment(0)
S
3

In case of Spring Boot 2.x.x or Spring 5, implements WebMvcConfigurer in the Swagger class configuration and add the followed annotations : @Component, @Configuration, @EnableSwagger2. Look at the below implementation :

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

}

The swagger version 2.9.2 is the most compatible if you are using Spring 5 or Spring Boot 2.x.x

Maven dependecies :

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

Checkout the swagger doc on : http://localhost:8080/context-root/swagger-ui.html

Steiner answered 7/12, 2020 at 17:0 Comment(0)
I
3

I am using springfox open API 3 and this worked perfectly for me:

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>

AppConfiguration

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

The resource path should point to the location of index.html in the jar see this image

Indices answered 12/5, 2021 at 4:14 Comment(1)
You don't really need dependecies: bootstrap, springfox-swagger2 (old version) and springfox-spring-web (which is transitive).Demimondaine
G
2

We ended up deploying Swagger-UI client separately and serving it through Nginx. We could not work out what's wrong with it and based on extensive research found many others having same difficulty so we decided to stop spending time on trying the embedded approach.

Garbo answered 11/5, 2017 at 10:55 Comment(0)
A
2

Had a similar problem and Dilips anwser worked. To be more precise:

  1. My api-docs location worked fine

  2. My swagger-ui.html was rendering but nothing viewed. In browser console i could see 404 for /configuration/ui dir.

the correct dir was /swagger-resources/configuration/ui so i had to do a redirection:

registry.addRedirectViewController("/configuration/ui", "/swagger-resources/configuration/ui");
Amaranthaceous answered 24/5, 2017 at 10:23 Comment(0)
B
2

I fixed the issue with this implementation:

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 don't forget to this in your gradle file

compile('org.springframework.boot:spring-boot-starter-security')
Brewington answered 18/9, 2019 at 13:51 Comment(0)
C
1

The same thing happened to me, for me it worked to go from version 3.0.0 to 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>
Corsage answered 8/3, 2021 at 19:43 Comment(0)
B
1

If you are using spring web MVC even in spring boot ,If there is @EnableWebMvc in your project by any chance then remove it. For me this was creating the problem.

Borries answered 30/3, 2022 at 5:44 Comment(0)
R
0

This is what works for me

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

Here is the pom:

   <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>
Rountree answered 31/7, 2019 at 7:10 Comment(0)
S
0

If you are using spring boot, that's all you need :

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

the configuration 4 swagger :

@Configuration
@EnableSwagger2
public class SwaggerConfig {

    @Bean
    public Docket api() {
        return new Docket(DocumentationType.SWAGGER_2).select().apis(RequestHandlerSelectors.any()).paths(PathSelectors.any()).build();
    }
}
Soave answered 16/9, 2019 at 14:41 Comment(0)
S
0

A new version of Swagger is available as of today's date: https://github.com/springfox/springfox

Better and easier configuration! I was upgrading Spring boot to 2.3.1 and adding swagger to my Microservices, was getting no mapping for the swaggger-ui.html after all proper configurations as mentioned in many of the answers above. Once I used this new version, all good!

Survey answered 30/7, 2020 at 8:45 Comment(0)
J
0

After few days of wondering I have finally found working answer, which should be correct for many maven problems - you just need to delete .m2/repository folder (it autorestores during 2 minutes) - and then you'll be able to update or downgrade any maven dependency, probably in this case they were swagger-ui and swagger2.

Jadda answered 9/12, 2021 at 3:54 Comment(0)
S
0

Changing
<version>3.0.0</version> to <version>2.9.1</version> Worked Fine For Me .

Spring Boot parent : 2.5.6

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

Swagger Dependencies :

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

    <dependency>
       <groupId>io.springfox</groupId>
       <artifactId>springfox-swagger-ui</artifactId>
       <version>2.9.1</version>
   </dependency>
Scant answered 25/4, 2022 at 4:35 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.