如何让Swagger使用@ApplicationPath?

时间:2018-02-21 18:43:16

标签: java jax-rs swagger

swagger-jaxrs 1.5.18

我在@ApplicationPath(“/ docs”)上有一个应用程序,在它下面是@Path(“/ mydocs”)的资源。因此真正的端点是/ api / docs / mydocs,但swagger.json中生成的是/ api / mydocs。

所需的招摇网址:/ api / docs / mydocs

实际的swagger网址:/ api / mydocs

要使其工作,必须做的是在应用程序中@ApplicationPath("")和参考资料中的@Path("/docs/mydocs"),但我不想任意改变所有路径,只是为了让它工作与Swagger。

There's a ticket on swagger's github that has been resolved, but for some reason it doesn't work for me (I am using what I think is the latest.)

@ApplicationPath( "/docs" )
@Api( tags = "docs" )
public class DocsConfig extends Application {

    public DocsConfig() {
        BeanConfig beanConfig = new BeanConfig();
        beanConfig.setVersion( "1.0" );
        beanConfig.setSchemes( new String[]{ "http" } );
        beanConfig.setHost( "localhost:8080" );
        beanConfig.setBasePath( "/api" );
        beanConfig.setResourcePackage( "com.my.company" );
        beanConfig.setScan( true );
        beanConfig.setTitle( "MY API" );

    }

    @Override
    public Set<Class<?>> getClasses() {
        Set<Class<?>> resources = new HashSet<>();
        resources.add( io.swagger.jaxrs.listing.ApiListingResource.class );
        resources.add( io.swagger.jaxrs.listing.SwaggerSerializers.class );
        resources.add( DocsResource.class );
        return resources;
    }
}

@Stateless
@Path( "/mydocs" )
@Api( value = "mydocs" )
public class DocsResource {

    @Context
    ServletContext servletContext;

    @Path( "/ui" )
    @GET
    public InputStream getFile() {
        //some stuff
    }
}

    <dependency>
        <groupId>io.swagger</groupId>
        <artifactId>swagger-jaxrs</artifactId>
        <version>1.5.18</version>
    </dependency>

1 个答案:

答案 0 :(得分:0)

正如评论中所提到的,仅在Swagger 2.0中添加了对@ApplicationPath的支持。使用Swagger 1.5,您可以选择在swagger config的基本路径中包含应用程序路径(如@imTachu所述):

final String applicationPath = DocsConfig.class.getAnnotation(ApplicationPath.class).value();
beanConfig.setBasePath("/api" + applicationPath);

这将导致生成的YAML看起来像这样:

...
basePath: "/api/docs"
...
paths:
  /mydocs/ui:
...

或者您可以编写一个ReaderListener来根据需要修改生成的Swagger:

@SwaggerDefinition
public class SwaggerBasePathModifier implements ReaderListener {

  @Override
  public void beforeScan(Reader aReader, Swagger aSwagger) {
    // do nothing
  }

  @Override
  public void afterScan(Reader aReader, Swagger aSwagger) {
    final Map<String, Path> newSwaggerPaths = new HashMap<>();
    final String applicationPath = DocsConfig.class.getAnnotation(ApplicationPath.class).value();
    for (final Map.Entry<String, Path> entry : aSwagger.getPaths().entrySet()) {
      final currKey = entry.getKey().substring("/api".length(), entry.getKey().length())
      final String newKey = "/api" + applicationPath + currKey;
      newSwaggerPaths.put(newKey, entry.getValue());
    }
    aSwagger.setPaths(newSwaggerPaths);
  }
}

这将导致生成的YAML中的每个路径都被修改。那就是你得到的:

...
basePath: "/api"
...
paths:
  /docs/mydocs/ui:
...

通过使用第一个选项,所有请求将使用相同的基本路径/api/docs,而后一个选项允许您配置多个基本路径(例如,对于在同一应用程序中配置的多个JAX-RS服务器),并且更多柔性的。