How to integrate swagger with jersey + spring-boot

16,264

I think @EnableSwagger2 annotation and springfox dependencies would work if the endpoints are implemented using Spring MVC instead of a JAX-RS implementation.

I blogged about this a few months ago, Microservices using Spring Boot, Jersey Swagger and Docker

Basically if you need to document your Jersey-implemented endpoints, you would need to:

1) Make sure your Spring Boot app scans for components located in specific packages (ie com.asimio.jerseyexample.config) via:

@SpringBootApplication(
    scanBasePackages = {
        "com.asimio.jerseyexample.config", "com.asimio.jerseyexample.rest"
    }
)

2) Jersey configuration class implementation:

package com.asimio.jerseyexample.config;
...
@Component
public class JerseyConfig extends ResourceConfig {

    @Value("${spring.jersey.application-path:/}")
    private String apiPath;

    public JerseyConfig() {
        // Register endpoints, providers, ...
        this.registerEndpoints();
    }

    @PostConstruct
    public void init() {
        // Register components where DI is needed
        this.configureSwagger();
    }

    private void registerEndpoints() {
        this.register(HelloResource.class);
        // Access through /<Jersey's servlet path>/application.wadl
        this.register(WadlResource.class);
    }

    private void configureSwagger() {
        // Available at localhost:port/swagger.json
        this.register(ApiListingResource.class);
        this.register(SwaggerSerializers.class);

        BeanConfig config = new BeanConfig();
        config.setConfigId("springboot-jersey-swagger-docker-example");
        config.setTitle("Spring Boot + Jersey + Swagger + Docker Example");
        config.setVersion("v1");
        config.setContact("Orlando L Otero");
        config.setSchemes(new String[] { "http", "https" });
        config.setBasePath(this.apiPath);
        config.setResourcePackage("com.asimio.jerseyexample.rest.v1");
        config.setPrettyPrint(true);
        config.setScan(true);
    }
}

3) Resource implementation using JAX-RS (Jersey) and Swagger annotations:

package com.asimio.jerseyexample.rest.v1;
...
@Component
@Path("/")
@Consumes(MediaType.APPLICATION_JSON)
@Produces(MediaType.APPLICATION_JSON)
@Api(value = "Hello resource", produces = "application/json")
public class HelloResource {

    private static final Logger LOGGER = LoggerFactory.getLogger(HelloResource.class);

    @GET
    @Path("v1/hello/{name}")
    @ApiOperation(value = "Gets a hello resource. Version 1 - (version in URL)", response = Hello.class)
    @ApiResponses(value = {
        @ApiResponse(code = 200, message = "Hello resource found"),
        @ApiResponse(code = 404, message = "Hello resource not found")
    })
    public Response getHelloVersionInUrl(@ApiParam @PathParam("name") String name) {
        LOGGER.info("getHelloVersionInUrl() v1");
        return this.getHello(name, "Version 1 - passed in URL");
    }
...
}

4) Make sure your app's Spring Boot configuration file makes a distinction between Spring MVC (for actuator endpoints) and Jersey (for resources) endpoints:

application.yml

...
# Spring MVC dispatcher servlet path. Needs to be different than Jersey's to enable/disable Actuator endpoints access (/info, /health, ...)
server.servlet-path: /
# Jersey dispatcher servlet
spring.jersey.application-path: /api
...
Share:
16,264
Joey Yi Zhao
Author by

Joey Yi Zhao

Updated on June 28, 2022

Comments

  • Joey Yi Zhao
    Joey Yi Zhao almost 2 years

    I am using springboot + jersey for web restful implementation. Now I am going to integrate swagger into our application. I did following.

    @Configuration
    @EnableSwagger2
    public class JerseyConfiguration extends ResourceConfig {
    
        public JerseyConfiguration(){
            register(HelloworldAPI.class);
            configureSwagger();
        }
    
        private void configureSwagger() {
            BeanConfig beanConfig = new BeanConfig();
            beanConfig.setVersion("1.0.2");
            beanConfig.setSchemes(new String[]{"http"});
            beanConfig.setHost("localhost:8080");
            beanConfig.setBasePath("/");
            beanConfig.setResourcePackage("com.cooltoo.api");
            beanConfig.setPrettyPrint(true);
            beanConfig.setScan(true);
        }
    }
    

    I added following dependences on build.gradle:

    compile('io.springfox:springfox-swagger2:'+springfoxSwaggerVersion)
    compile('io.springfox:springfox-petstore:'+springfoxSwaggerVersion)
    compile('io.springfox:springfox-swagger-ui:'+springfoxSwaggerVersion)
    compile('io.swagger:swagger-jersey2-jaxrs:1.5.8')
    

    I was able to launch the web application but I wander which url is for swagger? I tried with http://localhost:8080, http://localhost:8080/swagger, and http://localhost:8080/swagger-ui.html. But none of them could be accessed.

    • nerdherd
      nerdherd about 8 years
      Does your application have a context root? It should be available at swagger-ui.html relative to the context root.
    • Joey Yi Zhao
      Joey Yi Zhao about 8 years
      The context root is just "/".
  • RicardoS
    RicardoS over 4 years
    This works for SpringMVC, not for Jersey (jax-rs). As we see here: stackoverflow.com/a/38004323/976948
  • icyerasor
    icyerasor almost 4 years
    Can confirm this works. Seems like at least the @Api-Annotation is necessary for the Resource to get picked up during the scan. To also serve the static swagger-ui from a jersey + spring-boot app, see stackoverflow.com/questions/49882044/…