robertobado robertobado - 4 months ago 176
Java Question

Swagger routes return 404 on Spring Boot + Jersey

I am trying to add Swagger into an existing spring boot application as described in this tutorial.

My main application class is as follows:

@SpringBootApplication
@EnableAutoConfiguration
public class Application {
public static void main(String[] args) {
SpringApplication.run(Application.class, args);
}
}


Swagger configuration is:

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


I can see Spring apparently identifies Swagger and it's routes in startup log:

s.w.s.m.m.a.RequestMappingHandlerMapping : Mapped "{[/v2/api-docs],methods=[GET],produces=[application/json || application/hal+json]}" onto public org.springframework.http.ResponseEntity<springfox.documentation.spring.web.json.Json> springfox.documentation.swagger2.web.Swagger2Controller.getDocumentation(java.lang.String,javax.servlet.http.HttpServletRequest)
s.w.s.m.m.a.RequestMappingHandlerMapping : Mapped "{[/configuration/ui]}" onto org.springframework.http.ResponseEntity<springfox.documentation.swagger.web.UiConfiguration> springfox.documentation.swagger.web.ApiResourceController.uiConfiguration()
s.w.s.m.m.a.RequestMappingHandlerMapping : Mapped "{[/configuration/security]}" onto org.springframework.http.ResponseEntity<springfox.documentation.swagger.web.SecurityConfiguration> springfox.documentation.swagger.web.ApiResourceController.securityConfiguration()
s.w.s.m.m.a.RequestMappingHandlerMapping : Mapped "{[/swagger-resources]}" onto org.springframework.http.ResponseEntity<java.util.List<springfox.documentation.swagger.web.SwaggerResource>> springfox.documentation.swagger.web.ApiResourceController.swaggerResources()


but when trying to access
http://localhost:8080/v2/api-docs
, I get a plain 404 as response.

All the similar issues I could find online refer to people not using Spring Boot and having to manually map resources (also described in the same tutorial link), but this wouldn't be my case.

Any ideas how to fix it or - at least - where to proceed investigation?

Answer

I figured out the problem was related to jersey's application path configuration. In my case, through the following annotation:

@Component
@ApplicationPath("/") //WRONG
@Configuration
public class JerseyConfiguration extends ResourceConfig {
...
}

The @ApplicationPath configuration overrides any route published by Jersey itself (like the whitelabel /error) or third party libraries (in this case /v2/api-docs, /configuration/ui, /configuration/security and /swagger-resources from swagger). Having simply / as path forces request to be resolved strictly using custom controllers from my application.

Restricting @ApplicationPath to the actual paths served by the application (in my case /api) would allow jersey to bind other routes to auto generated controllers:

@Component
@ApplicationPath("/api") //RIGHT
@Configuration
public class JerseyConfiguration extends ResourceConfig {
...
}