通过 Swagger 使用多个 JAX-RS 应用程序类

问题描述 投票:0回答:2

我正在尝试在具有两个 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 文件:

我做错了什么?

感谢所有阅读的人!

java web-services jax-rs swagger swagger-2.0
2个回答
7
投票

默认情况下,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>

0
投票

我遇到了同样的问题,但使用的是 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

© www.soinside.com 2019 - 2024. All rights reserved.