configure swagger-ui with maven

zappee picture zappee · Apr 1, 2018 · Viewed 11.4k times · Source

I am integrating my JAX-RS REST project with Swagger. I read many documentation and tutorials and my favourite figure is the following (thanks to Philipp Hauer's blog):

enter image description here

That image helped me a lot to understand how Swagger works.

After I have learned how Swagger works I modified my pom.xml.

I added swagger-jersey2-jaxrs dependencies to my project which enable me to use swagger related annotations described here:

<!-- for Swagger-Core Annotations -->
<dependency>
    <groupId>io.swagger</groupId>
    <artifactId>swagger-jersey2-jaxrs</artifactId>
    <version>1.5.13</version>
</dependency>

Important: I am not able to use the latest 1.15.18 swagger-jersey2-jaxrs dependency because the guava library belongs to this dependency made a serious classloader issue with the latest (v5.181) Payara appserver:

  Exception Occurred :Error occurred during deployment: Exception while loading the app : java.lang.IllegalStateException: ContainerBase.addChild: start: org.apache.catalina.LifecycleException: org.apache.catalina.LifecycleException: java.lang.NoSuchMethodError: com.google.common.collect.Sets$SetView.iterator()Lcom/google/common/collect/UnmodifiableIterator;. Please see server.log for more details. ]]

Anyway, added the following plugin to my pom.xml as well which download the swagger-ui part and unpack it to the maven target folder:

<plugin>
    <groupId>com.googlecode.maven-download-plugin</groupId>
    <artifactId>download-maven-plugin</artifactId>
    <version>1.4.0</version>
    <executions>
        <execution>
            <id>swagger-ui</id>
            <phase>prepare-package</phase>
            <goals>
                <goal>wget</goal>
            </goals>
            <configuration>
                <url>https://github.com/swagger-api/swagger-ui/archive/v${version.swagger-ui}.tar.gz</url>
                <unpack>true</unpack>
                <outputDirectory>${project.build.directory}</outputDirectory>
            </configuration>
        </execution>
    </executions>
</plugin>

Here my issue was that I am behind proxy server so I had to add HTTPS proxy configuration to maven setting.xml.

Finnaly I added maven-war-plugin to the pom.xml which copy the swagger-ui related static files to my final war file:

<plugin>
    <groupId>org.apache.maven.plugins</groupId>
    <artifactId>maven-war-plugin</artifactId>
    <version>3.2.0</version>
    <configuration>
        <warName>${project.build.finalName}</warName>
        <webappDirectory>${basedir}/target/${project.build.finalName}</webappDirectory>
        <webResources>
            <webResource>
                <directory>${project.build.directory}/swagger-ui-${version.swagger-ui}/dist</directory>
                <targetPath>swagger</targetPath>
            </webResource>
        </webResources>
    </configuration>
</plugin>

I initialize swagger documentation generator with the following code:

@ApplicationPath("api")
public class Configurator extends Application {
    public Configurator() {
        BeanConfig beanConfig = new BeanConfig();
        beanConfig.setVersion("1.0.0");
        beanConfig.setSchemes(new String[]{"http"});
        beanConfig.setHost("localhost:8080");
        beanConfig.setBasePath("my-rest-1.0.0/api");
        beanConfig.setResourcePackage(EchoRest.class.getPackage().getName());
        beanConfig.setTitle("JAX-RS + Swagger and Swagger UI Example");
        beanConfig.setDescription("Sample RESTful API built using JAX-RS, Swagger and Swagger UI");
        beanConfig.setScan(true);
    }
}

It works fine, the http://localhost:8080/my-rest-1.2.0/api/swagger.json returns with a proper swagger documentation.

BUT

  1. I need to overwrite the hardcoded url value in the JavaScript part of the swagger/index.html file from the default http://petstore.swagger.io/v2/swagger.json to my URL. I download and copy swagger-ui via maven plugins automatically but I do not know how to change the value of the URL variable automatically during compiling with maven.
  2. The name of my WAR file depends on the version information used in maven pom.xml. That means that the hard-coded version, host and base-path used in Configurator class wont be correct after a while. Can I generate this values automatically based on the application root url and the value from @ApplicationPath("api") annotation?

Answer

noltedx picture noltedx · Mar 7, 2019

Especially to point one of your needs, we are using a replacer-plugin in maven to substitute the hardcoded url:

<!-- replace name of the specification file to show-->
            <plugin>
                <groupId>com.google.code.maven-replacer-plugin</groupId>
                <artifactId>replacer</artifactId>
                <executions>
                    <execution>
                        <phase>prepare-package</phase>
                        <goals>
                            <goal>replace</goal>
                        </goals>
                    </execution>
                </executions>
                <configuration>
                    <file>${project.build.directory}/swagger-ui/META-INF/resources/webjars/swagger-ui/${swagger-ui.version}/index.html</file>
                    <replacements>
                        <replacement>
                            <token>"https://petstore.swagger.io/v2/swagger.json"</token>
                            <value>location.protocol + '//' + location.hostname+':'+location.port+'/${project.artifactId}-${project.version}/Your-URL/openapi.json'</value>
                        </replacement>
                    </replacements>
                </configuration>
            </plugin>