在Swagger中使用多个JAX-RS应用程序类

db2dz4w8  于 5个月前  发布在  其他
关注(0)|答案(2)|浏览(65)

我试图在一个Java应用程序上实现Swagger,该应用程序有两个Application类,因为一个处理“公共”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文件:

我做错了什么?
感谢所有阅读的人!

ecr0jaav

ecr0jaav1#

默认情况下,Swagger只初始化扫描仪和配置一次。如果你有多个应用程序或服务器,你需要通过BeanConfig为每个应用程序设置一个scannerId,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配置中指定URL ID、contextId和scannerId作为init参数,如下所示。

<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>

iq3niunx

iq3niunx2#

我遇到了同样的问题,但与 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(servletConfig.servletContext.contextPath)
                )
            )
        }
        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。*

相关问题