How to integrate Swagger with Maven + Java + Jersey +Tomcat
Provided that you have correctly copied the files from https://github.com/wordnik/swagger-ui to your project (directory dist
must be copied to your src/main/webapp
), then you can access the API documentation on http://.../MyService/index.html
. Don't forget to modify index.html
so that Swagger knows where to load the API docs:
window.swaggerUi = new SwaggerUi({
url: "http://localhost:8080/MyService/rest/api-docs",
The API base path in your web.xml
must be set to http://.../MyService/rest
if rest
is the application path that you have defined in your implementation of class javax.ws.rs.core.Application
by using the annotation @ApplicationPath
.
Here is an example of what I usually do (I don't use web.xml
for configuration):
@ApplicationPath( "api" )
public class MyRestApplication extends Application
{
@Override
public Set<Class<?>> getClasses( )
{
Set<Class<?>> resources = new HashSet<Class<?>>( );
resources.add( ApiListingResource.class );
resources.add( ApiDeclarationProvider.class );
resources.add( ApiListingResourceJSON.class );
resources.add( ResourceListingProvider.class );
resources.add( Ping.class ); // my own resource class
swaggerConfiguration( );
return resources;
}
private void swaggerConfiguration( )
{
SwaggerConfig swaggerConfig = new SwaggerConfig( );
ConfigFactory.setConfig( swaggerConfig );
swaggerConfig.setApiVersion( "0.0.1" );
swaggerConfig.setBasePath( "http://localhost:8080/MyService/api" );
ScannerFactory.setScanner( new DefaultJaxrsScanner( ) );
ClassReaders.setReader( new DefaultJaxrsApiReader( ) );
}
}
The swagger.api.basepath
parameter is not where your Swagger installation keeps the index.html
. It is a parameter Swagger uses to offer you the capability to call your REST endpoints via the Swagger UI, so it get's rendered into the links Swagger uses.
You download the Swagger UI and put it into your WebContent
folder. You can then load the Swagger UI at http://localhost:8080/swagger/
.
The web.xml
should look like that:
<servlet>
<servlet-name>jersey-servlet</servlet-name>
<servlet-class>org.glassfish.jersey.servlet.ServletContainer</servlet-class>
<init-param>
<param-name>javax.ws.rs.Application</param-name>
<param-value>### Your Application or ResourceConfig ###</param-value>
</init-param>
<init-param>
<param-name>jersey.config.server.provider.packages</param-name>
<param-value>io.swagger.jaxrs.listing,
### com.your.rest.package ###
</param-value>
</init-param>
<load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>jersey-servlet</servlet-name>
<url-pattern>/rest/*</url-pattern>
</servlet-mapping>
...
<servlet>
<servlet-name>JerseyJaxrsConfig</servlet-name>
<servlet-class>io.swagger.jersey.config.JerseyJaxrsConfig</servlet-class>
<init-param>
<param-name>api.version</param-name>
<param-value>1.0.0</param-value>
</init-param>
<init-param>
<param-name>swagger.api.basepath</param-name>
<param-value>/MyService/rest</param-value>
</init-param>
<init-param>
<param-name>scan.all.resources</param-name>
<param-value>true</param-value>
</init-param>
<load-on-startup>2</load-on-startup>
</servlet>
Here is the simplest example using spring, tomcat, jersey, maven, swagger. Below is the project structure.
Code for HelloWorldService.
package com.rest;
import com.wordnik.swagger.annotations.Api;
import com.wordnik.swagger.annotations.ApiOperation;
import com.wordnik.swagger.annotations.ApiResponse;
import com.wordnik.swagger.annotations.ApiResponses;
import javax.ws.rs.GET;
import javax.ws.rs.Path;
import javax.ws.rs.PathParam;
import javax.ws.rs.Produces;
import javax.ws.rs.core.MediaType;
/**
* Created by neerbans on 11/3/2016.
*/
@Path("/hello")
@Api( value = "/hello", description = "print hello world")
public class HelloWorldService {
@ApiOperation(
value = "method api",
notes = "method api notes"
)
@ApiResponses(value = {
@ApiResponse(code = 200, message = "success"),
@ApiResponse(code = 500, message = "error")
})
@Produces({MediaType.TEXT_PLAIN})
@GET
@Path("/{param}")
public String getMsg(
@PathParam("param")
String msg
) {
String output = "Jersey say : " + msg;
return output;
}
}
SwaggerApp.class
package com.rest;
import com.wordnik.swagger.config.ConfigFactory;
import com.wordnik.swagger.config.ScannerFactory;
import com.wordnik.swagger.config.SwaggerConfig;
import com.wordnik.swagger.jaxrs.config.ReflectiveJaxrsScanner;
import com.wordnik.swagger.jaxrs.listing.ApiDeclarationProvider;
import com.wordnik.swagger.jaxrs.listing.ApiListingResource;
import com.wordnik.swagger.jaxrs.listing.ApiListingResourceJSON;
import com.wordnik.swagger.jaxrs.listing.ResourceListingProvider;
import com.wordnik.swagger.jaxrs.reader.DefaultJaxrsApiReader;
import com.wordnik.swagger.reader.ClassReaders;
import org.glassfish.jersey.message.MessageProperties;
import org.glassfish.jersey.server.ResourceConfig;
import org.glassfish.jersey.server.ServerProperties;
import javax.annotation.PostConstruct;
/**
* Created by neerbans on 11/3/2016.
*/
public class SwaggerApp extends ResourceConfig {
public SwaggerApp() {
register(HelloWorldService.class);
register(ApiListingResource.class);
register(ApiDeclarationProvider.class);
register(ApiListingResourceJSON.class);
register(ResourceListingProvider.class);
property(MessageProperties.XML_FORMAT_OUTPUT, true);
property(ServerProperties.TRACING, "ALL");
}
@PostConstruct
public void initializeSwaggerConfiguration() {
final ReflectiveJaxrsScanner scanner = new ReflectiveJaxrsScanner();
scanner.setResourcePackage("com.rest");
ScannerFactory.setScanner(scanner);
ClassReaders.setReader(new DefaultJaxrsApiReader());
final SwaggerConfig config = ConfigFactory.config();
config.setApiVersion("1.0");
config.setBasePath("http://localhost:8080/jax-rs/rest");
}
}
applicationContext.xml
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:context="http://www.springframework.org/schema/context" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.0.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-3.0.xsd">
<context:component-scan base-package="com.rest" />
<context:annotation-config />
</beans>
Web.xml
<!DOCTYPE web-app PUBLIC
"-//Sun Microsystems, Inc.//DTD Web Application 2.3//EN"
"http://java.sun.com/dtd/web-app_2_3.dtd" >
<web-app>
<display-name>Archetype Created Web Application</display-name>
<!--<servlet>-->
<!--<servlet-name>jersey-servlet</servlet-name>-->
<!--<servlet-class>com.sun.jersey.spi.container.servlet.ServletContainer</servlet-class>-->
<!--<init-param>-->
<!--<param-name>com.sun.jersey.config.property.packages</param-name>-->
<!--<param-value>com.rest</param-value>-->
<!--</init-param>-->
<!--<load-on-startup>1</load-on-startup>-->
<!--</servlet>-->
<context-param>
<param-name>contextConfigLocation</param-name>
<param-value>classpath:applicationContext.xml</param-value>
</context-param>
<listener>
<listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
</listener>
<listener>
<listener-class>org.springframework.web.context.request.RequestContextListener</listener-class>
</listener>
<servlet>
<servlet-name>Jersey Web Application</servlet-name>
<servlet-class>org.glassfish.jersey.servlet.ServletContainer</servlet-class>
<init-param>
<param-name>javax.ws.rs.Application</param-name>
<param-value>com.rest.SwaggerApp</param-value>
</init-param>
<load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>Jersey Web Application</servlet-name>
<url-pattern>/rest/*</url-pattern>
</servlet-mapping>
</web-app>
pom.xml
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
<parent>
<artifactId>nb</artifactId>
<groupId>com.edifecs</groupId>
<version>1.0-SNAPSHOT</version>
</parent>
<modelVersion>4.0.0</modelVersion>
<artifactId>jax-rs</artifactId>
<packaging>war</packaging>
<name>jax-rs Maven Webapp</name>
<url>http://maven.apache.org</url>
<dependencies>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>3.8.1</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.glassfish.jersey.containers</groupId>
<artifactId>jersey-container-servlet</artifactId>
<version>2.22.2</version>
</dependency>
<dependency>
<groupId>com.wordnik</groupId>
<artifactId>swagger-jaxrs_2.10</artifactId>
<version>1.3.12</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-web</artifactId>
<version>4.1.4.RELEASE</version>
</dependency>
</dependencies>
<build>
<finalName>jax-rs</finalName>
</build>
</project>
After setting the project. Build it and deploy the war file in Tomcat webapps folder.
Run Tomcat and hit below URLs :
http://localhost:8080/jax-rs/rest/api-docs
For swagger-ui
http://localhost:8080/jax-rs