title: Swagger 接口管理和文档导出
date: 2018-08-25 19:22:00
categories:
Springfox Swagger 和Spring的整合已经让我们可以动态的生成接口文档了,但是接口文档的生成、管理、导出在网上看了很多博客,着实让我走了很多弯路,都不是很满意。最终总结了一套实际可用的,希望此文不像其他人的文章那般晦涩难懂,给需要的人。
测试用例根据接口分组 批量循环生成对应的 swagger.json
接口分组管理请前往 《Spring MVC 组件配置 之 RESTFUL API文档以及Mock应用(springfox-swagger)》
此处分组分为api和ui,api部分为对外提供,ui为前端提供
SwaggerTest
:
package com.xxxx.xx.xxx.web.test;
import org.apache.commons.io.FileUtils;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.MediaType;
import org.springframework.mock.web.MockHttpServletResponse;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
import org.springframework.test.context.web.WebAppConfiguration;
import org.springframework.test.web.servlet.MockMvc;
import org.springframework.test.web.servlet.MvcResult;
import org.springframework.web.context.WebApplicationContext;
import java.io.BufferedWriter;
import java.nio.charset.StandardCharsets;
import java.nio.file.Files;
import java.nio.file.Paths;
import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.get;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status;
import static org.springframework.test.web.servlet.setup.MockMvcBuilders.webAppContextSetup;
/**
*
*
*
*
* @author xiachaoyang 2018年05月31日 10:21
* @version V1.0
* @modificationHistory=========================逻辑或功能性重大变更记录
* @modify by user: {修改人} 2018年05月31日
* @modify by reason:{方法名}:{原因}
*/
@RunWith(SpringJUnit4ClassRunner.class)
@WebAppConfiguration
@ContextConfiguration(locations = { "classpath:*-swt.xml"})
public class SwaggerTest {
@Autowired
private WebApplicationContext wac;
private MockMvc mockMvc;
/**
* 初始化 MOCK
*/
@Before
public void init() {
mockMvc = webAppContextSetup(wac).build();
}
/**
* 生成 swagger.json
*
* @throws Exception
*/
@Test
public void getSwaggerJson() throws Exception {
//获取插件中配置的swagger文件输出地址
String outputDir = System.getProperty("io.springfox.staticdocs.outputDir");
//获取插件中配置的swagger.json的访问地址,有几个接口分组就有几个访问地址,地址必须是swagger2controller中原生的,如果是在web.xml自定义的则无法访问,因为mock的服务不会解析web.xml
String uris = System.getProperty("io.swagger.json.uris");
//获取插件中配置的每个json文件的名称,名称可配置多个,有几个接口分组就有几个名称, 名称的格式必须是:组件标识-接口分组标识-接口版本号,例如:xxx-api-v1
String swaggerOutName = System.getProperty("io.swagger.json.output.name");
String[] uriArray = uris.trim().split(",");
String[] swaggerOutNameArray = swaggerOutName.trim().split(",");
//清空文件夹
//FileUtils.deleteDirectory(Paths.get(outputDir).toFile());
for (int i = 0; i < uriArray.length; i++) {
MvcResult mvcResult = mockMvc
.perform((get(uriArray[i]))
.accept(MediaType.APPLICATION_JSON_UTF8))
.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, swaggerOutNameArray[i]), StandardCharsets.UTF_8)) {
writer.write(swaggerJson);
}
}
}
}
添加配置文件
index.adoc
:
include::{generated}/overview.adoc[]
include::{generated}/paths.adoc[]
include::{generated}/security.adoc[]
include::{generated}/definitions.adoc[]
config.properties
:
swagger2markup.markupLanguage = ASCIIDOC
swagger2markup.outputLanguage = EN
生成adoc文件
Swagger2Markup
:
package com.xxxx.xx.xxx.web.test;
import io.github.swagger2markup.Swagger2MarkupConfig;
import io.github.swagger2markup.Swagger2MarkupConverter;
import io.github.swagger2markup.builder.Swagger2MarkupConfigBuilder;
import java.net.URL;
import java.nio.file.Path;
import java.nio.file.Paths;
import org.apache.commons.configuration2.Configuration;
import org.apache.commons.configuration2.builder.fluent.Configurations;
/**
*
*
*
*
* @author xiachaoyang
* @version V1.0
* @date 2018年08月21日 9:45
* @modificationHistory=========================逻辑或功能性重大变更记录
* @modify By: {修改人} 2018年08月21日
* @modify reason: {方法名}:{原因}
* ...
*/
public class Swagger2Markup {
private static String[] restKeys = new String[]{"ui","api"};//"ui"
//指定adoc文件生成路径
private static Path outputDirectory;
//通过配置文件生成swagger2markup的参数
public Swagger2MarkupConfig config;
public Swagger2Markup(String Json) throws Exception{
//读取配置文件
Configuration configuration = new Configurations().properties("config.properties");
config = new Swagger2MarkupConfigBuilder(configuration).build();
if(Json.startsWith("http")){
//获取远程json数据
createAdocFile(new URL(Json));
}else{
//获取本地json数据
createAdocFile(Paths.get(Json));
}
}
/**
* 通过url生成adoc文件
*/
public void createAdocFile(URL remoteSwaggerFile){
Swagger2MarkupConverter.from(remoteSwaggerFile)
.withConfig(config)
.build()
.toFolder(outputDirectory);
}
/**
* 通过json文件生成adoc文件
*/
public void createAdocFile(Path localSwaggerFile){
Swagger2MarkupConverter.from(localSwaggerFile)
.withConfig(config)
.build()
.toFolder(outputDirectory);
}
public static void main(String[] args) throws Exception{
//循环生成json对应的acdoc
for(String key:restKeys){
outputDirectory = Paths.get("xxx-web/target/asciidoc/generated/"+key);
//指定本地json文件路径
new Swagger2Markup("xxx-web/target/swagger/xxx-"+key+"-v1.json");
}
//指定远程json文件路径
// new Swagger2Markup("http://petstore.swagger.io/v2/swagger.json");
}
}
配置插件执行 生成 pdf 和 html 格式的接口文档
由于
配置,接口分组id不同,调整参数执行mvn compile(或在idea中的maven project中点击可视化命令也可以) 2次即可。
yyyyMMddHHmmss
api
ui
${rest.ui.path}
${project.basedir}/src/docs/asciidoc
${project.build.directory}/asciidoc/generated
${project.build.directory}/asciidoc/html
${project.build.directory}/asciidoc/pdf
${project.build.directory}/rest-docs/rest-docs_${maven.build.timestamp}
文件重命名分类存放
执行mvn compile
、mvn test
分别生成html和pdf的接口文档,文档分类重命名放到指定文件夹(此处对maven生命周期不了解的同学请自行百度)
maven 插件重命名文件并移动
插件配置
:
org.asciidoctor
asciidoctor-maven-plugin
1.5.3
org.asciidoctor
asciidoctorj-pdf
1.5.0-alpha.10.1
org.jruby
jruby-complete
1.7.21
${asciidoctor.input.directory}
index.adoc
book
left
3
${generated.asciidoc.directory}/${rest.swagger.path}
output-html
compile
process-asciidoc
html5
${asciidoctor.html.output.directory}/${rest.swagger.path}
output-pdf
compile
process-asciidoc
pdf
${asciidoctor.pdf.output.directory}/${rest.swagger.path}
com.coderplus.maven.plugins
copy-rename-maven-plugin
rename-file-pdf-api
test
rename
${asciidoctor.pdf.output.directory}/${rest.api.path}/index.pdf
${swagger.output.zip}/pdf/xxx-api-${rest.api.version}.pdf
rename-file-pdf-ui
test
rename
${asciidoctor.pdf.output.directory}/${rest.ui.path}/index.pdf
${swagger.output.zip}/pdf/xxx-ui-${rest.ui.version}.pdf
rename-file-html-api
test
rename
${asciidoctor.html.output.directory}/${rest.api.path}/index.html
${swagger.output.zip}/html/xxx-api-${rest.api.version}.html
rename-file-html-ui
test
rename
${asciidoctor.html.output.directory}/${rest.ui.path}/index.html
${swagger.output.zip}/html/xxx-ui-${rest.ui.version}.html
rename-file-json-api
test
rename
${project.build.directory}/swagger/xxx-api-${rest.api.version}.json
${swagger.output.zip}/json/xxx-api-${rest.api.version}.json
rename-file-json-ui
test
rename
${project.build.directory}/swagger/xxx-ui-${rest.ui.version}.json
${swagger.output.zip}/json/xxx-ui-${rest.ui.version}.json
然后将文件夹压缩给需要接口的人即可
asciidoctor-pdf 【github】
asciidoctor-maven-plugin 【github】
通过swagger2markup+asciidoctorj生成html和pdf文档并解决asciidoctorj生成的pdf文件中文显示不全问题(maven方式及java代码方式)
maven打包加时间戳方法总结
扫码关注“架构探险之道”,获取更多源码和文章资源
知识星球(扫码加入获取源码和文章资源链接)