Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Unable to bring up swagger-ui from spring-boot application

Tags:

I have a spring boot application that i am running using embedded tomcat server. I am partially successful in getting springfox-swagger integrated with the app. If i do a /v2/api-docs , i am able to see all the documentation of all the api's in the webapp. However, when i am trying to access the same from UI, it does not work. Below are the detailed results.

Output of - localhost:8080/api/swagger-resources

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

Output of - localhost:8080/api/v2/api-docs

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

But when i try to access the swagger-ui, it does not work. Below are the different URL's i invoked to access the 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 

Below is my SwaggerConfig.java class

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

Below are the swagger dependencies i am using

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

Below is the message converter webconfig file

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

The below link says that @EnableWebMvc should not be used in a spring-boot webapp and using the annotation might cause issues in bringing swagger-ui up. But, if i do not use the annotation, the web-app is not coming up (i have pasted the error stack trace below)

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

Error trace when i don't use the @EnableWebMvc Annotation

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) 

I have a feeling that i am missing something trivial. Can someone please take a look and let me know what i am missing.?? Thanks in advance.!!

like image 872
Naveen Chandra Avatar asked Aug 25 '15 01:08

Naveen Chandra


People also ask

How do I open Swagger UI spring boot?

To enable the Swagger2 in Spring Boot application, you need to add the following dependencies in our build configurations file. For Gradle users, add the following dependencies in your build. gradle file. Now, add the @EnableSwagger2 annotation in your main Spring Boot application.

How do I get to Swagger UI?

Go to http://localhost:8000/ in your address bar. This address lets you view the local web server. By default, web servers default to the index. html file in the directory, so it will show the Swagger UI file automatically.

Which URL should be used to access the Swagger UI after starting the application?

Once your application is started, you can go to http://localhost:8080/q/swagger-ui and play with your API.


2 Answers

If you want to keep @EnableWebMvc annotation any way, you have to add the following

  @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/");      } 
like image 63
maruf571 Avatar answered Oct 12 '22 14:10

maruf571


springfox-swagger-ui is a web jar and requires that you set up resource handlers to inform the dispatch servlet how and which resource to serve up when you ask for ../swagger-ui.html. Usually in a spring-boot application auto-configuration takes care of setting it up for you. The reason its not loading in your case is because you've signaled to spring-boot that the application is going to be manually configured via the WebMvcConfigurerAdapter/@EnableWebMvc combination.

You should be able to place the @SpringBootApplication annotation on your main spring configuration and get rid of the WebConfig class all-together.

Since your WebConfig isn't adding any value other than making sure the JSON is indented, I'd suggest removing it all-together and replacing it with a Jackson2ObjectMapperBuilder bean instead.

For examples on how to do the same thing in spring-mvc/spring-boot etc. take a look at the springfox-demos project. In particular take a look at SpringConfig to see how to manually configure the resource handlers.

like image 37
Dilip Krishnan Avatar answered Oct 12 '22 15:10

Dilip Krishnan