Skip to content

Instantly share code, notes, and snippets.

Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save biniama/2270cf1389a5c18df59251f7441fd8ca to your computer and use it in GitHub Desktop.
Save biniama/2270cf1389a5c18df59251f7441fd8ca to your computer and use it in GitHub Desktop.
Setup Swagger with an embedded Jetty Server

Swagger Setup for Embedded Jetty Server

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:

  1. Add the package scanning packages to your servlets which will serve your REST API.
  2. Add the Swagger package scanning servlet.
  3. 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

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/*");

Add the package scanning packages to your servlets which will serve your REST API

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

Add the Swagger package scanning servlet

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.

Package the Swagger-UI static HTML5 content with your server

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.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment