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.x.x. With Swagger UI version 4.x.x 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 enable reading config params from URL by setting the queryConfigEnabled parameter to true but it's not working for me (I understand that there are security concerns). I found this page (https://cwiki.apache.org/confluence/display/CXF20DOC/OpenApiFeature) very close to what I am looking for but I couldn't locate any example on how to set queryConfigEnabled for the swaggerUiConfig property in my web.xml. Could someone please help me by providing examples of how to set this?
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