我个人是一直使用Swagger作为接口文档的说明的。但是由于在一些情况下,接口文档说明需要以文件的形式交付出去,如果再重新写一份文档难免有些麻烦。于是在网上看到了Swagger2Markup + asciidoctor导出PDF的方法,百度一番后感觉网上的文章还是有很多没有描述清楚的地方,遂还是硬着头皮把官方的英文文档大致浏览了一下,按照自己的思路整理出具体的步骤。
本文用到的工具:
Gradle - 4.10.3
SpringBoot - 2.1.6.RELEASE
Swagger - 2.9.2
Swagger2Markup - 1.3.3
asciidoctor
spring-restdocs-mockmvc
准备Swagger数据SpringBoot中使用Swagger的过程就不再赘述了,下面是本文使用的范例:
@Configuration @EnableSwagger2 class SwaggerConfig { @Bean public Docket createRestApi() { return new Docket(DocumentationType.SWAGGER_2) .apiInfo(apiInfo()) .select() .apis(RequestHandlerSelectors.basePackage("com.jptangchina.gradle.controller")) .paths(PathSelectors.any()) .build(); } private ApiInfo apiInfo() { return new ApiInfoBuilder() .title("Swagger2Markup Test Api") .version("1.0") .build(); } } @RestController @RequestMapping("/user") @Api(tags = "用户接口") public class UserController { @ApiOperation("用户登录") @ResponseBody @PostMapping("/login") public Result<Void> login( @ApiParam(value = "用户名", example = "jptangchina", required = true) @RequestParam String username, @ApiParam(value = "密码", example = "jptangchina", required = true) @RequestParam String password) { return Result.ok(); } } 使用org.asciidoctor.convert生成PDF(个人不推荐使用)官方教程地址:https://github.com/Swagger2Markup/spring-swagger2markup-demo
仅为了简单的导出PDF而言,本文针对官方案例均有所改动,去掉了部分没有用到的配置。
1. 获取Swagger json文件Swagger页面本质上也就是对json文件进行解析。这里需要先编写单元测试访问/v2/api-docs接口并将json文件保存到本地。
@RunWith(SpringRunner.class) @SpringBootTest @AutoConfigureMockMvc class SwaggerTest { @Autowired private MockMvc mockMvc; @Test public void generateAsciiDocsToFile() throws Exception { String outputDir = System.getProperty("io.springfox.staticdocs.outputDir"); MvcResult mvcResult = this.mockMvc.perform(get("/v2/api-docs") .accept(MediaType.APPLICATION_JSON)) .andExpect(status().isOk()) .andReturn(); MockHttpServletResponse response = mvcResult.getResponse(); String swaggerJson = response.getContentAsString(); Files.createDirectories(Paths.get(outputDir)); try (BufferedWriter writer = Files.newBufferedWriter(Paths.get(outputDir, "swagger.json"), StandardCharsets.UTF_8)){ writer.write(swaggerJson); } } }System.getProperty("io.springfox.staticdocs.outputDir");来自于build.gradle中的配置
2. 将json文件转换为adoc文件转换json文件需要使用到io.github.swagger2markup插件的convertSwagger2markup方法。
引入相关依赖:
buildscript { ... dependencies { ... classpath 'io.github.swagger2markup:swagger2markup-gradle-plugin:1.3.3' } } apply plugin: 'io.github.swagger2markup'配置convertSwagger2markup:
ext { asciiDocOutputDir = file("${buildDir}/asciidoc") swaggerOutputDir = file("${buildDir}/swagger") } test { systemProperty 'io.springfox.staticdocs.outputDir', swaggerOutputDir } convertSwagger2markup { dependsOn test swaggerInput "${swaggerOutputDir}/swagger.json" outputDir asciiDocOutputDir config = [ 'swagger2markup.pathsGroupedBy' : 'TAGS', ] }更多config配置可以参考:#_swagger2markup_properties
3. 将adoc文件转换为PDF文件转换PDF文件需要用到org.asciidoctor.convert插件的asciidoctor方法。
引入相关依赖:
手动编写index.adoc文件,放置到${asciiDocOutputDir.absolutePath}中:
include::{generated}/overview.adoc[] include::{generated}/paths.adoc[] include::{generated}/definitions.adoc[] include::{generated}/security.adoc[]{generated}默认值为${build}/asciidoc,参见:https://github.com/Swagger2Markup/swagger2markup-gradle-project-template
配置asciidoctor:
asciidoctor { dependsOn convertSwagger2markup // sourceDir中需要包含有之前手动编写的index.adoc文件 sourceDir(asciiDocOutputDir.absolutePath) sources { include "index.adoc" } backends = ['pdf'] attributes = [ doctype: 'book', toc: 'left', toclevels: '3', numbered: '', sectlinks: '', sectanchors: '', hardbreaks: '', generated: asciiDocOutputDir ] } 4. 编写一个自定义task用来执行上述流程: task genPdf(type: Test, dependsOn: test) { include '**/*SwaggerTest.class' exclude '**/*' dependsOn(asciidoctor) }执行genPdf,就可以生成Swagger对应的PDF文件。
5. 小结使用此方法步骤还是比较繁琐的,总体来讲就是json -> adoc -> pdf,并且使用此种方法目前有几个比较大的问题我仍然没有找到解决方案: