Forum Discussion

smunigal's avatar
smunigal
Occasional Visitor
2 years ago

How to configure Swagger UI's URL with Apache CXF?

We are using Apache CXF for Swagger in our webapp (deployed in Tomcat) to display REST endpoints of our application. Everything is configured and is working perfectly until we upgraded Swagger UI from 3.52.5 to version 4.****. With Swagger UI version 4.**** we always get the default Petstore API . I found that the reason for this is https://github.com/swagger-api/swagger-ui/issues/7702 We use the  url  parameter, which is getting ignored as reading config params from URL is disabled for security reasons. URL we use: http://host:port/webappname/doc/api-docs?url=/webappname/doc/openapi.json#/

 

I am trying to set the config url in the code as mentioned in the https://github.com/reta/description_openapi_v3_web sample. But it is not working. Could you please look into it and do the needful. Providing the required details, let me know if you need any other.

 

Sample web.xml:

 

  <servlet>

    <servlet-name>MyServlet</servlet-name>

    <servlet-class>

          org.apache.cxf.jaxrs.servlet.CXFNonSpringJaxrsServlet

    </servlet-class>

    <init-param>

      <param-name>javax.ws.rs.Application</param-name>

      <param-value>com.abc.xyz.MyApp</param-value>

    </init-param>

    <init-param>

        <param-name>redirects-list</param-name>

        <param-value>

        .*\.jsp

        .*\.jspx

        </param-value>

    </init-param>

    <init-param>

        <param-name>redirect-servlet-name</param-name>

        <param-value>mvc-dispatch</param-value>

    </init-param>

    <init-param>

        <param-name>static-resources-list</param-name>

        <param-value>

        /index.html

        .*\.html

        .*\.htm

        .*\.json

        .*\.js

        </param-value>

    </init-param>

    <init-param>

      <param-name>static-welcome-file</param-name>

      <param-value>/index.html</param-value>

    </init-param>

    <load-on-startup>1</load-on-startup>

  </servlet>

 

  <servlet>

        <display-name>REST API Documentation</display-name>

        <servlet-name>RestAPIDoc</servlet-name>

        <servlet-class>org.apache.cxf.jaxrs.servlet.CXFNonSpringJaxrsServlet</servlet-class>

        <init-param>

            <param-name>jaxrs.serviceClasses</param-name>

            <param-value>com.abc.xyz.AgentManagerService</param-value>

        </init-param>

        <init-param>

            <param-name>jaxrs.features</param-name>

            <param-value>org.apache.cxf.jaxrs.openapi.OpenApiFeature</param-value>

        </init-param>

        <init-param>

            <param-name>jaxrs.providers</param-name>

            <param-value>

                org.apache.cxf.jaxrs.provider.MultipartProvider,

                com.fasterxml.jackson.jaxrs.json.JacksonJsonProvider

            </param-value>

        </init-param>

                <load-on-startup>1</load-on-startup>

    </servlet>

   

    <servlet-mapping>

        <servlet-name>RestAPIDoc</servlet-name>

        <url-pattern>/doc/*</url-pattern>

    </servlet-mapping>

 

MyApp class:

 

public class MyApp extends Application {

    private Set<Object> singletons = new HashSet<Object>();

    private Set<Class<?>> classes = new HashSet<Class<?>>();

    public MyApp() throws ServletException {

        try {

           

            singletons.add(new JSONProvider());

            singletons.add(new WARProvider());

            Context m_context = getNamingContext();

           

            /* WS-Implementation for REST Transport Management */

            RestTransportManagerService restTransportManagerService = new RestTransportManagerService(m_context);

            singletons.add(restTransportManagerService);

            /* WS-Implementation for SOAP Transport Management */

            SoapTransportManagerService soapTransportManagerService = new SoapTransportManagerService(m_context);

            singletons.add(soapTransportManagerService);

            /* Added few more services in this way */

            AgentManagerService agentManagerService = new AgentManagerService();

            singletons.add(agentManagerService);

        }

        catch (Exception e) {

            String errorMessage = e.getMessage();

            ResponseBuilderImpl errorResponse =  new ResponseBuilderImpl();

            errorResponse.status(Response.Status.INTERNAL_SERVER_ERROR);

            errorResponse.entity(errorMessage);

            throw new ServletException(e.getMessage());

        }

    }

    private Context getNamingContext() throws NamingException{

        Context m_context = new InitialContext();

        NamingContext envContext = (NamingContext)m_context.lookup("java:comp/env");

        return m_context;

    }

    @Override

    public Set<Class<?>> getClasses() {

        return classes;

    }

    @Override

    public Set<Object> getSingletons() {

        final OpenApiFeature feature = new OpenApiFeature();

        feature.setSwaggerUiConfig(

                new SwaggerUiConfig()

                    .url("/oemanager/doc/openapi.json")

                    .queryConfigEnabled(true));

        singletons.add(feature);

        return singletons;

    }

}

Versions Used:

CXF: 3.5.1 (can upgrade to latest CXF if required (https://mvnrepository.com/artifact/org.apache.cxf/cxf-core)

Swagger UI: 4.13.2 (Open for any version in 4 series (https://mvnrepository.com/artifact/org.webjars/swagger-ui)

JDK: openjdk version "17.0.3"

Platform: Windows

Container: Tomcat 9.0.64

  • nehakakar's avatar
    nehakakar
    Occasional Contributor

    Update your MyApp class to include the Swagger UI configuration.

     

    import org.apache.cxf.jaxrs.openapi.OpenApiFeature;
    import org.apache.cxf.jaxrs.swagger.ui.SwaggerUiConfig;
    
    public class MyApp extends Application {
        // ...
    
        @Override
        public Set<Object> getSingletons() {
            final OpenApiFeature feature = new OpenApiFeature();
    
            // Set the Swagger UI configuration
            SwaggerUiConfig uiConfig = new SwaggerUiConfig()
                    .url("/webappname/doc/openapi.json") // Set the URL of your swagger.json file
                    .queryConfigEnabled(true);
            feature.setSwaggerUiConfig(uiConfig);
    
            singletons.add(feature);
            return singletons;
        }
    }

     

    In your web.xml, update the servlet and servlet-mapping to map the URL of your Swagger UI.

     

    <servlet>
        <display-name>REST API Documentation</display-name>
        <servlet-name>RestAPIDoc</servlet-name>
        <servlet-class>org.apache.cxf.jaxrs.servlet.CXFNonSpringJaxrsServlet</servlet-class>
        <init-param>
            <param-name>jaxrs.serviceClasses</param-name>
            <param-value>com.abc.xyz.AgentManagerService</param-value>
        </init-param>
        <init-param>
            <param-name>jaxrs.features</param-name>
            <param-value>org.apache.cxf.jaxrs.openapi.OpenApiFeature</param-value>
        </init-param>
        <init-param>
            <param-name>jaxrs.providers</param-name>
            <param-value>
                org.apache.cxf.jaxrs.provider.MultipartProvider,
                com.fasterxml.jackson.jaxrs.json.JacksonJsonProvider
            </param-value>
        </init-param>
        <load-on-startup>1</load-on-startup>
    </servlet>
    
    <servlet-mapping>
        <servlet-name>RestAPIDoc</servlet-name>
        <url-pattern>/doc/*</url-pattern>
    </servlet-mapping>

     

    Make sure your swagger.json file is available at the specified URL (/webappname/doc/openapi.json) and contains the correct API definition for your application.

    I hope it helps.