Springfox Swagger - 在使用Spring Boot、Jersey和Gradle时无法生成API文档

5
我有一个使用Jersey和Gradle的Spring Boot应用程序,并尝试使用Springfox自动生成API文档。
我按照此处的步骤进行操作:http://springfox.github.io/springfox/docs/current/ 以下是我的操作步骤:
  • build.gradle:

    dependencies {
        .........
        //Swagger
        compile "io.springfox:springfox-swagger2:2.4.0"
        compile "io.springfox:springfox-bean-validators:2.4.0"
        compile 'io.springfox:springfox-swagger-ui:2.4.0'
    }
    
  • Spring boot Application:

    @SpringBootApplication
    @EnableSwagger2
    public class AnalyzerServiceApplication{
    
    public static void main(String[] args) {
        SpringApplication.run(AnalyzerServiceApplication.class, args);
    }
    
    @Bean
    public Docket analyzerApi() {
    return new Docket(DocumentationType.SWAGGER_2)
    .select()
        .apis(RequestHandlerSelectors.any())
        .paths(PathSelectors.any())
        .build()
    .pathMapping("/")
    .directModelSubstitute(LocalDate.class, String.class)
    .genericModelSubstitutes(ResponseEntity.class)
    .alternateTypeRules(
        newRule(typeResolver.resolve(DeferredResult.class,
        typeResolver.resolve(ResponseEntity.class, WildcardType.class)),
        typeResolver.resolve(WildcardType.class)))
    .useDefaultResponseMessages(false)
    .globalResponseMessage(RequestMethod.GET,
        newArrayList(new ResponseMessageBuilder()
            .code(500)
            .message("500 message")
            .responseModel(new ModelRef("Error"))
            .build()))
    .securitySchemes(newArrayList(apiKey()))
    .securityContexts(newArrayList(securityContext()))
    .enableUrlTemplating(true)
    .globalOperationParameters(
        newArrayList(new ParameterBuilder()
            .name("someGlobalParameter")
            .description("Description of someGlobalParameter")
            .modelRef(new ModelRef("string"))
            .parameterType("query")
            .required(true)
            .build()))
        .tags(new Tag("Pet Service", "All apis relating to pets")) 
        ;
    }
    
    @Autowired
    private TypeResolver typeResolver;
    
    private ApiKey apiKey() {
        return new ApiKey("mykey", "api_key", "header");
    }
    
    private SecurityContext securityContext() {
        return SecurityContext.builder()
            .securityReferences(defaultAuth())
            .forPaths(PathSelectors.regex("/anyPath.*"))
            .build();
    }
    
    List<SecurityReference> defaultAuth() {
        AuthorizationScope authorizationScope
            = new AuthorizationScope("global", "accessEverything");
            AuthorizationScope[] authorizationScopes = new AuthorizationScope[1];
        authorizationScopes[0] = authorizationScope;
        return newArrayList(
            new SecurityReference("mykey", authorizationScopes));
    }
    
    @Bean
    SecurityConfiguration security() {
        return new SecurityConfiguration(
            "test-app-client-id",
            "test-app-client-secret",
            "test-app-realm",
            "test-app",
            "apiKey",
            ApiKeyVehicle.HEADER, 
            "api_key", 
            "," /*scope separator*/);
    }
    
    @Bean
    UiConfiguration uiConfig() {
        return new UiConfiguration("validatorUrl");
    }
    
  • Now the controller (Jersey)

    @Api(value = "/widget")
    @Path("/widget")
    @Component
    public class WidgetController extends BaseController {
    
    @Autowired
    private WidgetService widgetService;
    
    @GET
    @Path("/secHealth")
    @ApiOperation(value = "Find pet by ID", notes = "Returns a pet when ID < 10.  ID > 10 or nonintegers will simulate API error conditions", response = Pet.class)
    @ApiResponses(value = { @ApiResponse(code = 400, message = "Invalid ID supplied"),
    @ApiResponse(code = 404, message = "Pet not found") })
    public Response getPet() {
        //Do something
    }
    
当我启动服务器并导航到http://localhost:8080/swagger-ui.html时,我可以看到“绿色”UI屏幕,只列出了基本错误控制器。我的控制器不在那里。
我做错了什么?
谢谢 Guy

你是否能够在“v2/api-docs”路径后面获取生成的Swagger定义? - Shibashis
是的。但它只包含/error路径。它无法识别WidgetController。为什么? - Guy Hudara
你确定 springfox 支持 Jersey 控制器吗?文档说它支持 Spring MVC... 可能默认情况下它正在寻找 Spring @Controller 注释... - jny
我完全不确定 springfox 是否支持 Jersey。我已经尝试过使用 @Controller 注释,但没有成功。你知道除了 springfox 外,还有哪些模块可以与 spring-boot、jersey 和 gradle 一起使用吗? - Guy Hudara
3个回答

12
截至版本2.5.0springfox仅支持spring-mvc控制器。不支持像jersey这样的jax-rs实现。
目前在jax-rs/jersey服务中使用swagger-core库是一种替代方案。
它具有实施在2.6+中支持jersey所需的钩子。以下是实现此方法的摘录this issue

当前ResourceConfig具有一个名为“ getClasses”的方法,该方法将列出所有已注册的内容。例如资源、过滤器等...也许这可以帮助你。但请注意,返回的类也可能是过滤器或您可以在jersey2中注册的任何其他内容。


谢谢。我会尝试这个。 - Guy Hudara

8
为了能够在Springfox Swagger UI中查看Jersey方法,请按以下步骤操作:
  1. 使用Jersey配置Swagger,可以参考https://github.com/swagger-api/swagger-core/wiki/Swagger-Core-Jersey-2.X-Project-Setup-1.5
  2. 使用Springfox Swagger配置Swagger,可以参考http://springfox.github.io/springfox/docs/current/
  3. 在你的SpringBoot应用程序配置类中(使用@ Configuration注释),添加以下内容:

    @Value("${springfox.documentation.swagger.v2.path}") private String swagger2Endpoint;

  4. 在application.properties文件中,引用你的Jersey swagger.json:

    springfox.documentation.swagger.v2.path=/{change it to your Jersey api path}/swagger.json

现在,你应该可以从Springfox Swagger UI页面查看Jersey Swagger生成的API。

4

感谢@Dilip-Krishnan更新了Springfox,同时感谢@Guy-Hudara的提问,我想出了以下解决方案,在我的SpringBoot Jersey应用中实现swagger支持:

import io.swagger.jaxrs.config.BeanConfig;
import io.swagger.jaxrs.listing.ApiListingResource;
import io.swagger.jaxrs.listing.SwaggerSerializers;
import org.glassfish.jersey.server.ResourceConfig;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Configuration;

import javax.annotation.PostConstruct;

/**
 * As of version 2.5.0 springfox only supports spring-mvc controllers. Jax-rs implementations like jersey aren't supported.
 *
 * Fortunately io.swagger::swagger-jersey2-jaxrs::1.5.3 have the hooks needed to implement support for jersey in 2.6+.
 *
 * some pointers I used to get this swagger config done and swagger-core, springboot and jersey integrated:
 * https://dev59.com/7Jfga4cB1Zd3GeqPALtR
 * https://www.insaneprogramming.be/blog/2015/09/04/spring-jaxrs/
 * https://github.com/swagger-api/swagger-core/wiki/Swagger-Core-Jersey-2.X-Project-Setup-1.5#adding-the-dependencies-to-your-application
 *
 */
@Configuration
public class SwaggerConfiguration {

    @Autowired
    ResourceConfig resourceConfig;

    @PostConstruct
    public void configure() {

        resourceConfig.register(ApiListingResource.class);
        resourceConfig.register(SwaggerSerializers.class);

        BeanConfig beanConfig = new BeanConfig();
        beanConfig.setVersion("1.0.2");
        beanConfig.setSchemes(new String[]{"http"});
        beanConfig.setHost("localhost:8888");
        beanConfig.setBasePath("/api");
        beanConfig.setResourcePackage("com.my.resource");
        beanConfig.setPrettyPrint(true);
        beanConfig.setScan(true);

    }
}

那对我来说非常好


那么,使用上面的代码,是否需要下载Swagger-UI压缩文件并将其提取到类路径的某个位置? - jkerak
哦,当然,你需要从某个地方提供单页应用程序Swagger UI,上面的内容只是为了生成Swagger JSON规范。 - Francois

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接