我正在尝试在具有两个 Application 类的 Java 应用程序上实现 Swagger,因为一个处理“公共”Web 服务,另一个处理“管理”Web 服务。我正在尝试生成两个单独的 swagger.json 文件,每个 Application 类一个。然而,这两个 URL 只生成其中之一。这是一些代码:
公开申请类:
@WebServlet
@ApplicationPath("/public")
public class PublicApplication extends Application {
public PublicApplication() {
BeanConfig beanConfig = new BeanConfig();
beanConfig.setVersion("1.0");
beanConfig.setTitle("A Fine Title");
beanConfig.setDescription("A Fine Description.");
beanConfig.setSchemes(new String[]{"http"});
beanConfig.setBasePath("/api");
beanConfig.setResourcePackage("com.test.rest.resource.external");
beanConfig.setPrettyPrint(true);
beanConfig.setScan(true);
}
}
私人申请课程:
@WebServlet
@ApplicationPath("/admin")
public class AdminApplication extends Application {
public AdminApplication() {
BeanConfig beanConfig = new BeanConfig();
beanConfig.setVersion("1.0");
beanConfig.setTitle("Another Fine Title");
beanConfig.setDescription("Another Fine Description.");
beanConfig.setSchemes(new String[]{"http"});
beanConfig.setBasePath("/apiTwo");
beanConfig.setResourcePackage("com.test.rest.resource.internal");
beanConfig.setPrettyPrint(true);
beanConfig.setScan(true);
}
}
现在,如果我点击这些网址中的任何一个,我都会得到相同的“公共”swagger json 文件:
我做错了什么?
感谢所有阅读的人!
默认情况下,Swagger 会对扫描仪和配置进行一次初始化。如果您有多个应用程序或配置,则需要通过
BeanConfig
为每个应用程序设置 configId、scannerId 和 contextId,并且这应与 servlet 配置中的值匹配。我认为此设置仅适用于最新版本的 swagger。我尝试使用 swagger-1.5.13。下面显示了一个示例。
public class PublicApplication extends Application {
public PublicApplication() {
BeanConfig beanConfig = new BeanConfig();
beanConfig.setVersion("1.0");
beanConfig.setTitle("A Fine Title");
beanConfig.setDescription("A Fine Description.");
beanConfig.setSchemes(new String[]{"http"});
beanConfig.setBasePath("/api");
beanConfig.setResourcePackage("com.test.rest.resource.external");
beanConfig.setPrettyPrint(true);
// Set configId,contextId & scannerId
beanConfig.setConfigId("public");
beanConfig.setContextId("public");
beanConfig.setScannerId("public");
beanConfig.setScan(true);
}
您的 AdminApplication 类
public AdminApplication() {
BeanConfig beanConfig = new BeanConfig();
beanConfig.setVersion("1.0");
beanConfig.setTitle("Another Fine Title");
beanConfig.setDescription("Another Fine Description.");
beanConfig.setSchemes(new String[]{"http"});
beanConfig.setBasePath("/apiTwo");
beanConfig.setResourcePackage("com.test.rest.resource.internal");
beanConfig.setPrettyPrint(true);
// Set configId,contextId & scannerId
beanConfig.setConfigId("admin");
beanConfig.setContextId("admin");
beanConfig.setScannerId("admin");
beanConfig.setScan(true);
beanConfig.setScan(true);
}
您还应该在 servlet 配置中指定 configId、contextId 和 ScannerId 作为初始化参数,如下所示。
<servlet>
<servlet-name>jersey-rest-public</servlet-name>
<servlet-class>org.glassfish.jersey.servlet.ServletContainer</servlet-class>
<init-param>
<param-name>javax.ws.rs.Application</param-name>
<param-value>com.test.rest.resource.PublicApplication</param-value>
</init-param>
<init-param>
<param-name>swagger.scanner.id</param-name>
<param-value>public</param-value>
</init-param>
<init-param>
<param-name>swagger.context.id</param-name>
<param-value>public</param-value>
</init-param>
<init-param>
<param-name>swagger.config.id</param-name>
<param-value>public</param-value>
</init-param>
<load-on-startup>1</load-on-startup>
</servlet>
<servlet>
<servlet-name>jersey-rest-admin</servlet-name>
<servlet-class>org.glassfish.jersey.servlet.ServletContainer</servlet-class>
<init-param>
<param-name>javax.ws.rs.Application</param-name>
<param-value>com.test.rest.resource.AdminApplication</param-value>
</init-param>
<init-param>
<param-name>swagger.context.id</param-name>
<param-value>admin</param-value>
</init-param>
<init-param>
<param-name>swagger.scanner.id</param-name>
<param-value>admin</param-value>
</init-param>
<init-param>
<param-name>swagger.config.id</param-name>
<param-value>admin</param-value>
</init-param>
<load-on-startup>1</load-on-startup>
</servlet>
我遇到了同样的问题,但使用的是 swagger v3。 我花了一些功夫才解决这个问题,所以我想分享它。
import io.swagger.v3.jaxrs2.Reader
import io.swagger.v3.jaxrs2.integration.JaxrsApplicationScanner
import io.swagger.v3.jaxrs2.integration.JaxrsOpenApiContext
import io.swagger.v3.oas.annotations.Operation
import io.swagger.v3.oas.models.OpenAPI
import io.swagger.v3.oas.models.info.Info
import io.swagger.v3.oas.models.servers.Server
import javax.enterprise.inject.Instance
import javax.inject.Inject
import javax.servlet.ServletConfig
import javax.ws.rs.GET
import javax.ws.rs.Path
import javax.ws.rs.Produces
import javax.ws.rs.core.Application
import javax.ws.rs.core.Context
import javax.ws.rs.core.MediaType
@Path("/openapi.json")
open class OpenApiPath {
@field:Inject
private lateinit var applications: Instance<Application>
@field:Context
private lateinit var servletConfig: ServletConfig
private val openApi by lazy { initOpenApi() }
@GET
@Produces(MediaType.APPLICATION_JSON)
@Operation(hidden = true)
open fun getSchema() = openApi
private fun initOpenApi(): OpenAPI {
val initial = OpenAPI().apply {
info(Info().title("Application title"))
servers(
listOf(
Server().url("/context-path")
)
)
}
val applications = applications.toList()
val openApi = applications.fold(initial) { initial, app ->
val context = JaxrsOpenApiContext<JaxrsOpenApiContext<*>>()
context.app(app)
context.setOpenApiReader(Reader(initial).apply { setApplication(app) })
context.setOpenApiScanner(JaxrsApplicationScanner().application(app))
context.read()
}
return openApi
}
}
如果您已在
Application
类中注册了所有 jaxrs 资源,则此方法有效。
别忘了注册
io.swagger.v3.jaxrs2.SwaggerSerializers
。