Setting basePath at runtime from a configuration file with java jaxrs jersey implementation

7,231 views
Skip to first unread message

Kevin O'Connor

unread,
Aug 23, 2013, 4:50:08 PM8/23/13
to swagger-sw...@googlegroups.com
I'm looking for some guidance on how to go about setting the basePath from a properties file at runtime instead of within the web descriptor.  

I am also using spring so I have been able to set the basePath at runtime using BeanConfig but if I go that route, I can't find a way to specify the swagger.filter that I have configured for the DefaultJaxrsConfig servlet. 

Can anyone help?

Thanks much.

Kevin O'Connor

unread,
Aug 23, 2013, 5:03:37 PM8/23/13
to swagger-sw...@googlegroups.com
I saw a virtual duplicate topic below that helped me find a solution.

I extended DefaultJaxRsConfig and used the ConfigFactory.config().setBasePath() method.

tony tam

unread,
Aug 23, 2013, 5:27:08 PM8/23/13
to swagger-sw...@googlegroups.com
Thanks for reporting back--this needs to get into the wiki.

Vibha

unread,
Aug 26, 2013, 2:21:48 AM8/26/13
to swagger-sw...@googlegroups.com
Is there a way I can set basePath using a spring-managed bean? i.e. the class that extends DefaultJaxRsConfig is a spring-managed bean. The above solution did not help me.

Vibha

unread,
Aug 26, 2013, 6:50:19 AM8/26/13
to swagger-sw...@googlegroups.com
Also I do not want to load set ConfigFactory.config().setBasePath() in a static block. Is there any other way of doing it?

tony tam

unread,
Aug 26, 2013, 11:17:00 AM8/26/13
to swagger-sw...@googlegroups.com
Not sure exacty what you mean.  If you look in the logic in the BeanConfig class, you should be able to replicate that logic in any bean you like, managed or not.

Vibha

unread,
Aug 27, 2013, 4:25:52 AM8/27/13
to swagger-sw...@googlegroups.com
I have integrated swagger jaxrs 1.3 with my spring+jersey implementation and have added all my configuration in web.xml. Everything is working fine except that I cannot read the config properties from a properties file using Spring since my CustomBootstrap expects the properties to be loaded at class load time (i.e. setting basePath in a static block). Is there a way to make the CustomBootstrap as a spring bean so that I can set the basePath after the CustomBootstrap is initialized by the spring container?

Eyal Allweil

unread,
Aug 27, 2013, 10:24:32 AM8/27/13
to swagger-sw...@googlegroups.com
It's not ideal, by any means, but one thing you can do is set the Swagger basepath after a fixed delay, so that Spring loads your service (and presumably, a dynamic basePath variable) before setting it.

Here is a code snippet:

@PostConstruct
    public void setBasePath() {
        ScheduledExecutorService executorService=Executors.newSingleThreadScheduledExecutor();
        executorService.schedule(new Runnable() {
            @Override
            public void run() {
                SwaggerConfig config = new SwaggerConfig();
                config.setBasePath(yourBasePathVariable);
                ConfigFactory.setConfig(config);
            }
        }, 30, TimeUnit.SECONDS); // waits thirty seconds before configuring Swagger basepath so that Swagger doesn't overwrite it
    }

If someone has a more elegant solution, I, too, will be glad to hear it - but this works for me.

Roland Tepp

unread,
Sep 16, 2013, 9:25:03 AM9/16/13
to swagger-sw...@googlegroups.com
Can anyone spell it out for me, as I am totally new to this and getting lost with all the terms that are being juggled around.

So what I have:
I do have a working setup that has Jersey+Spring+Swagger defined in web.xml:

<?xml version="1.0" encoding="UTF-8"?>
<!--suppress ServletWithoutMappingInspection -->
         version="2.5">

    <display-name>My Web Application</display-name>

    <context-param>
        <param-name>contextConfigLocation</param-name>
        <param-value>WEB-INF/spring.xml</param-value>
    </context-param>

    <listener>
        <listener-class>
            org.springframework.web.context.ContextLoaderListener
        </listener-class>
    </listener>

    <servlet>
        <servlet-name>rest</servlet-name>
        <servlet-class>com.sun.jersey.spi.spring.container.servlet.SpringServlet</servlet-class>
        <init-param>
            <param-name>com.sun.jersey.config.property.packages</param-name>
            <param-value>my.app.path.package;com.wordnik.swagger.jersey.listing</param-value>
        </init-param>
        <load-on-startup>1</load-on-startup>
    </servlet>

    <servlet>
        <servlet-name>api-docs</servlet-name>
        <servlet-class>com.wordnik.swagger.jaxrs.config.DefaultJaxrsConfig</servlet-class>
        <init-param>
            <param-name>api.version</param-name>
            <param-value>1.0</param-value>
        </init-param>
        <init-param>
            <param-name>swagger.api.version</param-name>
            <param-value>1.3</param-value>
        </init-param>
        <init-param>
            <param-name>swagger.api.basepath</param-name>
            <param-value>http://localhost:8080/my-app</param-value>
        </init-param>
        <load-on-startup>2</load-on-startup>
    </servlet>

    <servlet-mapping>
        <servlet-name>rest</servlet-name>
        <url-pattern>/rest/*</url-pattern>
    </servlet-mapping>
</web-app>

I would like to update the swagger.api.basepath configuration value at runtime (preferably using Spring configuration).

What should I do? I suppose I can get rid of the api-doc servlet somehow?
(the app will run eventually on customized embedded Jetty, but I suppose that should not matter too much?)

tony tam

unread,
Sep 16, 2013, 11:34:04 AM9/16/13
to swagger-sw...@googlegroups.com
Hi Roland, it's very easy to set the base path programmatically.  Here are some pointers.

1) If you are using spring, you can use the applicationContext.xml to load a Bean which then sets the values.  This would be a replacement for your web.xml configuration--see https://github.com/wordnik/swagger-core/wiki/Java-CXF-Quickstart

2) Using the web.xml approach, you can still override the basepath.  Simply create a bootstrap class and configure it at startup:

package com.wordnik.swagger.sample;

import com.wordnik.swagger.jaxrs.*;
import com.wordnik.swagger.config.*;
import com.wordnik.swagger.model.*;

public class Bootstrap extends HttpServlet {
  static {
    // do any additional initialization here
    ConfigFactory.config().setBasePath("http://www.foo.com/");
  }
}

and in web.xml:

  <servlet>
    <servlet-name>Bootstrap</servlet-name>
    <servlet-class>com.wordnik.swagger.sample.Bootstrap</servlet-class>
    <load-on-startup>2</load-on-startup>
  </servlet>

Roland Tepp

unread,
Sep 17, 2013, 7:44:17 AM9/17/13
to swagger-sw...@googlegroups.com
Yes, thanks,

after reading this through for several times and then filling in some blanks that I had due to the fact that I have scant previous experience with many of the technologies involved, here is the final configuration:

web.xml:
<?xml version="1.0" encoding="UTF-8"?>
<!--suppress ServletWithoutMappingInspection -->
<web-app xmlns="http://java.sun.com/xml/ns/javaee"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd"
         version="2.5">

    <display-name>MSSA Proxy Web Application</display-name>


    <context-param>
        <param-name>contextConfigLocation</param-name>
        <param-value>WEB-INF/spring.xml</param-value>
    </context-param>

    <listener>
        <listener-class>
            org.springframework.web.context.ContextLoaderListener
        </listener-class>
    </listener>

    <servlet>
        <servlet-name>rest</servlet-name>
        <servlet-class>com.sun.jersey.spi.spring.container.servlet.SpringServlet</servlet-class>
        <init-param>
            <param-name>com.sun.jersey.api.json.POJOMappingFeature</param-name>
            <param-value>true</param-value>

        </init-param>
        <load-on-startup>1</load-on-startup>
    </servlet>

    <servlet-mapping>
        <servlet-name>rest</servlet-name>
        <url-pattern>/rs/*</url-pattern>
    </servlet-mapping>

    <welcome-file-list>
        <!-- Swagger UI entry point -->
        <welcome-file>index.jsp</welcome-file>
    </welcome-file-list>

</web-app>


spring.xml:
    <!-- Needed this for JAXB json serialization -->
    <bean id="jacksonJaxbJsonProvider" class="com.fasterxml.jackson.jaxrs.json.JacksonJaxbJsonProvider" scope="singleton">
        <constructor-arg>
            <list>
                <value>JAXB</value>
                <value>JACKSON</value>
            </list>
        </constructor-arg>
    </bean>


    <!-- Swagger API listing resource -->
    <bean id="swaggerResourceJSON" class="com.wordnik.swagger.jaxrs.listing.ApiListingResourceJSON" />

    <!-- Swagger writers -->
    <bean id="resourceWriter" class="com.wordnik.swagger.jaxrs.listing.ResourceListingProvider" scope="singleton" />
    <bean id="apiWriter" class="com.wordnik.swagger.jaxrs.listing.ApiDeclarationProvider" scope="singleton" />

    <!-- Swagger configuration -->
    <bean id="swaggerConfig" class="com.wordnik.swagger.jaxrs.config.BeanConfig">
        <property name="resourcePackage" value="my.resource.packages.root" />
        <property name="version" value="1.0" />
        <property name="basePath" value="http://localhost:8080/rs" />

        <property name="title" value="Swagger API documentation" />
        <property name="description" value="Swagger on a Spring!" />

        <property name="scan" value="true" />
    </bean>

This configuration seems to work.
Reply all
Reply to author
Forward
0 new messages