In setting up a Jetty server with Jersey servlets, you may choose to use an embedded Jetty server setup. (See here for how to setup an embedded Jetty server). In this gist, we'll go through how to setup Swagger for this setup. I am using Swagger 1.5, Maven 3.3.3, Jersey 1.8, and Jetty 7.3. Make sure you add all dependencies to your pom.xml.
In the Swagger Core setup, the current official recommendations involve an Application class, or a web.xml, neither of which are used in an embedded Jetty server setup. To add Swagger to your embedded Jetty Server, you must do 3 things:
- Add the package scanning packages to your servlets which will serve your REST API.
- Add the Swagger package scanning servlet.
- Package the Swagger-UI static HTML5 content with your server
Let's start with a basic server class, adapted from the Eclipse tutorial above.
public class MyServer {
public static void main(String[] args) throws Exception
{
Server server = new Server(8080);
ServletContextHandler context = new ServletContextHandler(ServletContextHandler.SESSIONS);
context.setContextPath("/");
server.setHandler(context);
// Setup API resources
ServletHolder apiServlet = context.addServlet(ServletContainer.class, "/api/*");
apiServlet.setInitOrder(1);
apiServlet.setInitParameter("com.sun.jersey.config.property.packages", "com.api.resources");
server.start();
server.join();
}
}
Our package setup is very minimal:
- src
- main
- java
- MyServer.java
- resources
- java
- main
In this example, the servlet serving the API is initialized as a ServletContainer and has its values instantiated in-code. However, if you choose to make your own servlet class, then you will need to set parameters in that class instead, and you can then add a servlet like so:
ServletHolder apiServlet = context.addServlet(new MyServlet(), "/path/*");
First, to add the Swagger package scanning classes. Usually one would add them to the web.xml like this. In your embedded Jetty servlet setup, you are setting the packages you are serving via the "com.sun.jersey.config.property.packages"
property. So, add the io.swagger.jaxrs.json;io.swagger.jaxrs.listing
packages to your servlet setup, like so:
public class MyServer {
public static void main(String[] args) throws Exception
{
Server server = new Server(8080);
ServletContextHandler context = new ServletContextHandler(ServletContextHandler.SESSIONS);
context.setContextPath("/");
server.setHandler(context);
ServletHolder apiServlet = context.addServlet(ServletContainer.class, "/api/*");
apiServlet.setInitOrder(1);
apiServlet.setInitParameter("com.sun.jersey.config.property.packages", "com.api.resources;io.swagger.jaxrs.json;io.swagger.jaxrs.listing");
server.start();
server.join();
}
}
Now, to configure and initialize Swagger. Based on these instructions, you'll now manually create and add the Swagger servlet. The path provided for the Swagger servlet is irrelevant, as it is not actually accessed through this path. However, make sure it does not collide with any of your other resource paths!
public class MyServer {
public static void main(String[] args) throws Exception
{
Server server = new Server(8080);
ServletContextHandler context = new ServletContextHandler(ServletContextHandler.SESSIONS);
context.setContextPath("/");
server.setHandler(context);
// Setup API resources
ServletHolder apiServlet = context.addServlet(ServletContainer.class, "/api/*");
apiServlet.setInitOrder(1);
apiServlet.setInitParameter("com.sun.jersey.config.property.packages", "com.api.resources;io.swagger.jaxrs.json;io.swagger.jaxrs.listing");
// Setup Swagger servlet
ServletHolder swaggerServlet = context.addServlet(DefaultJaxrsConfig.class, "/swagger-core");
swaggerServlet.setInitOrder(2);
swaggerServlet.setInitParameter("api.version", "1.0.0");
server.start();
server.join();
}
}
Now, when you navigate to http://<host>:8080/api/swagger.json
, Swagger will generate a JSON response detailing your resource paths, their parameters, and their responses.
However, most people prefer a more human readable method -- so we will now package the Swagger-UI HTML5 project with your server.
To your pom.xml, you need to add the ability to download and and then copy the Swagger-UI static resources to your project's resources folder. That way when you package and run your server eventually via java -cp <libs> MyServer.class
, it will be able to display the Swagger UI at http:://<host>:8080/
.
Similar to here, we will add the following lines to our pom.xml, in the <build></build>
portion:
<!-- Download the Swagger-UI project -->
<build>
<plugins>
...
<plugin>
<groupId>com.googlecode.maven-download-plugin</groupId>
<artifactId>download-maven-plugin</artifactId>
<version>1.2.1</version>
<executions>
<execution>
<id>swagger-ui</id>
<phase>validate</phase>
<goals>
<goal>wget</goal>
</goals>
<configuration>
<url>https://github.com/swagger-api/swagger-ui/archive/v2.1.1.tar.gz</url>
<unpack>true</unpack>
<outputDirectory>${project.build.directory}</outputDirectory>
</configuration>
</execution>
</executions>
</plugin>
<!-- Load the Swagger-UI components into the src/main/webapp/ directory to enable
viewing/testing of the API routes. Accessible at http://<host>:<port>/swagger. -->
<plugin>
<artifactId>maven-resources-plugin</artifactId>
<version>2.7</version>
<executions>
<execution>
<id>copy-resources</id>
<phase>initialize</phase>
<goals>
<goal>copy-resources</goal>
</goals>
<configuration>
<outputDirectory>${basedir}/src/main/resources/webapp</outputDirectory>
<resources>
<resource>
<directory>${project.build.directory}/swagger-ui-2.1.1/dist</directory>
</resource>
</resources>
</configuration>
</execution>
</executions>
</plugin>
</plugins>
</build>
When you run mvn clean package
on your project, this will first download the Swagger-UI into target
folder. Then, the dist
folder of the Swagger-UI project is copied into the /resources/webapp
folder of your main project. When compiled, the webapp
folder will then appear in target/classes
, and be accessible to your compiled and running server JAR.
Now, you have to point your ServletContextHandler to these static resources. Begin by using your MyServer
class to find the resource, then set the welcome file to be the name of the desired HTML file (in this case, 'index.html'). Update your ServletContextHandler's resource base path to point to the static resources. Finally, add a DefaultServlet to serve these static resources. This DefaultServlet must be the last servlet added to your ServletContextHandler.
public class MyServer {
public static void main(String[] args) throws Exception
{
Server server = new Server(8080);
ServletContextHandler context = new ServletContextHandler(ServletContextHandler.SESSIONS);
context.setContextPath("/");
server.setHandler(context);
// Setup API resources
ServletHolder apiServlet = context.addServlet(ServletContainer.class, "/api/*");
apiServlet.setInitOrder(1);
apiServlet.setInitParameter("com.sun.jersey.config.property.packages", "com.api.resources;io.swagger.jaxrs.json;io.swagger.jaxrs.listing");
// Setup Swagger servlet
ServletHolder swaggerServlet = context.addServlet(DefaultJaxrsConfig.class, "/swagger-core");
swaggerServlet.setInitOrder(2);
swaggerServlet.setInitParameter("api.version", "1.0.0");
// Setup Swagger-UI static resources
String resourceBasePath = ServicesRunner.class.getResource("/webapp").toExternalForm();
context.setWelcomeFiles(new String[] {"index.html"});
context.setResourceBase(resourceBasePath);
context.addServlet(new ServletHolder(new DefaultServlet()), "/*");
server.start();
server.join();
}
}
Now, when you start up your server via usr/bin/java -cp <libs> MyServer
, you should be able to navigate to http://<host>:8080
and see the Swagger-UI welcome page, similar to this demo page. Enter your api Swagger paths (e.g. http://<host>:8080/api/swagger.json
) in order to see your API Resources Swagger-fied.