转自:https://blog.csdn.net/seanxwq/article/details/78064599
最近因为项目中需要编写接口文档,原来用的swagger结合现有项目问题比较多,且没有直观的目录(不知道swagger是否有左边栏目录这样的形式,没去细查),配合前端和测试使用时,他们抱怨比较多,所以摒弃了swagger之后,找到了spring rest docs, 结合官方文档和网上查到的资料,成功生成了接口文档。样例如下:
spring rest docs的使用其实就是在你现有的spring mvc或spring boot的项目上,配置生成文档的依赖包,然后编写接口单元测试,编写adoc配置文件,最后打包自动生成html接口文档的过程。根据这个步骤一步步操作:
1、配置依赖:
-
<dependency>
-
<groupId>org.springframework.restdocs
</groupId>
-
<artifactId>spring-restdocs-mockmvc
</artifactId>
-
<scope>test
</scope>
-
</dependency>
-
<build>
-
<plugins>
-
<plugin>
-
<groupId>org.springframework.boot
</groupId>
-
<artifactId>spring-boot-maven-plugin
</artifactId>
-
</plugin>
-
<plugin>
-
<groupId>org.asciidoctor
</groupId>
-
<artifactId>asciidoctor-maven-plugin
</artifactId>
-
<version>1.5.3
</version>
-
<executions>
-
<execution>
-
<id>generate-docs
</id>
-
<phase>prepare-package
</phase>
-
<goals>
-
<goal>process-asciidoc
</goal>
-
</goals>
-
<configuration>
-
<backend>html
</backend>
-
<doctype>book
</doctype>
-
</configuration>
-
</execution>
-
</executions>
-
<dependencies>
-
<dependency>
-
<groupId>org.springframework.restdocs
</groupId>
-
<artifactId>spring-restdocs-asciidoctor
</artifactId>
-
<version>1.2.1.RELEASE
</version>
-
</dependency>
-
</dependencies>
-
</plugin>
-
<plugin>
-
<artifactId>maven-resources-plugin
</artifactId>
-
<version>2.7
</version>
-
<executions>
-
<execution>
-
<id>copy-resources
</id>
-
<phase>prepare-package
</phase>
-
<goals>
-
<goal>copy-resources
</goal>
-
</goals>
-
<configuration>
-
<outputDirectory>
-
${project.build.outputDirectory}/static/docs</div></div></li><li><div class="hljs-ln-numbers"><div class="hljs-ln-line hljs-ln-n" data-line-number="45"></div></div><div class="hljs-ln-code"><div class="hljs-ln-line"> <span class="hljs-tag"></<span class="hljs-name">outputDirectory</span>></span></div></div></li><li><div class="hljs-ln-numbers"><div class="hljs-ln-line hljs-ln-n" data-line-number="46"></div></div><div class="hljs-ln-code"><div class="hljs-ln-line"> <span class="hljs-tag"><<span class="hljs-name">resources</span>></span></div></div></li><li><div class="hljs-ln-numbers"><div class="hljs-ln-line hljs-ln-n" data-line-number="47"></div></div><div class="hljs-ln-code"><div class="hljs-ln-line"> <span class="hljs-tag"><<span class="hljs-name">resource</span>></span></div></div></li><li><div class="hljs-ln-numbers"><div class="hljs-ln-line hljs-ln-n" data-line-number="48"></div></div><div class="hljs-ln-code"><div class="hljs-ln-line"> <span class="hljs-tag"><<span class="hljs-name">directory</span>></span></div></div></li><li><div class="hljs-ln-numbers"><div class="hljs-ln-line hljs-ln-n" data-line-number="49"></div></div><div class="hljs-ln-code"><div class="hljs-ln-line"> ${project.build.directory}/generated-docs
-
</directory>
-
</resource>
-
</resources>
-
</configuration>
-
</execution>
-
</executions>
-
</plugin>
-
</plugins>
-
</build>
2、编写接口测试
我们通过mock进行接口测试编写,测试类属性配置及单测前的before方法:
-
@Rule
-
public JUnitRestDocumentation restDocumentation =
new JUnitRestDocumentation(
"target/generated-snippets");
//生成的adoc文件导出目录
-
private MockMvc mockMvc;
-
@Autowired
-
private WebApplicationContext context;
-
-
@Before
-
public void setUp() {
-
this.mockMvc = MockMvcBuilders.webAppContextSetup(
this.context)
-
.apply(documentationConfiguration(
this.restDocumentation))
-
// .alwaysDo(document("{method-name}/{step}/"))
-
.build();
-
}
单测例子(与普通的mock测试多了红色标注的部分,语法什么的我就不在这里讲解了,要想写出来,肯定要看官方文档: 点击打开链接,如果不想看英文,看这个博客也可以: 点击打开链接,不过,还是强烈推荐看官方文档):
-
@Test
-
public void contextLoads() throws Exception {
-
this.mockMvc.perform(get(
"/hello?page=2&per_page=100").accept(MediaType.APPLICATION_JSON).header(
"Authorization",
"Basic dXNlcjpzZWNyZXQ="))
-
.andDo(print()).andExpect(status().isOk())
-
.andDo(document(
"hello 接口",
//这个identity不同的单测需要不同,否则其他的测试会覆盖现有的,最后文档里只生成一个接口说明
-
requestHeaders(
-
headerWithName(
"Authorization").description(
-
"Basic auth credentials")),
-
requestParameters(
-
parameterWithName(
"page").description(
"The page to retrieve"),
-
parameterWithName(
"per_page").description(
"Entries per page")
-
)));
-
}
3、编写adoc配置文件
在maven项目标准结构下,src/main下新建asciidoc目录,并建一个.adoc为结尾的文件(到时候打包时,会根据asciidoc目录下的所有.adoc文件生成过个对应文件名的html文档)。例子如下:
-
<span style=
"color:#ff6666;">== hello 接口</span>
-
.http-
request
-
include::D:\ideaworkspace\restdoc\target\generated-snippets\hello 接口\http-
request.adoc[]
-
.
request-headers 请求头说明
-
include::D:\ideaworkspace\restdoc\target\generated-snippets\hello 接口\
request-headers.adoc[]
-
.
request-parameters 请求参数说明
-
include::D:\ideaworkspace\restdoc\target\generated-snippets\hello 接口\
request-parameters.adoc[]
-
.http-
response
-
include::D:\ideaworkspace\restdoc\target\generated-snippets\hello 接口\http-
response.adoc[]
-
-
<span style=
"color:#ff6666;">== hello2 接口</span>
-
.http-
request
-
include::D:\ideaworkspace\restdoc\target\generated-snippets\hello2 接口\http-
request.adoc[]
-
.http-
response
-
include::D:\ideaworkspace\restdoc\target\generated-snippets\hello2 接口\http-
response.adoc[]
4、ok,最后用maven打包项目,跑完之后,就可以在target/generated-docs下看到你的文件了,直接双击打开,就能看到生成的文档。
以上是根据官网文档,就可以导出一个接口文档。但是,并没有左边栏的目录,而且写一个单测就要在.adoc文件里添加include关键字导入新生成的接口内容很麻烦,怎么办呢?
首先,左边栏目录或右边栏目录,或直接在文档最开头添加目录我们只需要在.adoc文件开头添加如下内容:
-
= 接口文档
-
v1
.0,
2017
-09
-22
-
:toc:
left
它会自动根据你文件下发的接口配置来定义目录,前面第3点列出的那个配置红色部分就是接口的引用配置。是不是很简单,配置完之后,就能生成和我文档最开头那张图片的样子了。
然后解决每写一个接口测试就要在.adoc文件里添加include的问题:
我们编写.adoc文件生成功能,方法如下(参考了:点击打开链接):
-
@Test
-
public void adocBuild() throws IOException {
-
String appDir = System.getProperty(
"user.dir");
-
String adocPath = appDir +
"\src\main\asciidoc\hello.adoc";
-
StringBuilder content =
new StringBuilder();
-
content.append(
"include::" + appDir +
"\src\main\asciidoc\preview.adoc[]").append(System.getProperty(
"line.separator")).append(System.getProperty(
"line.separator"));
-
File apidirs =
new File(appDir +
"\target\generated-snippets");
-
for (File apidir : apidirs.listFiles()) {
-
String apiName = apidir.getName();
-
content.append(
"== " + apiName + System.getProperty(
"line.separator"));
-
fileAppend(content, apidir +
"\http-request.adoc",
".http-request");
-
fileAppend(content, apidir +
"\request-headers.adoc",
".request-headers 请求头说明");
-
fileAppend(content, apidir +
"\request-parameters.adoc",
".request-parameters 请求参数说明");
-
fileAppend(content, apidir +
"\request-body.adoc",
".request-body 请求体说明");
-
fileAppend(content, apidir +
"\http-response.adoc",
".http-response");
-
fileAppend(content, apidir +
"\response-fields.adoc",
".response-fields 返回值说明");
-
content.append(System.getProperty(
"line.separator"));
-
}
-
// System.out.println(adocPath);
-
// System.out.println(content);
-
File file =
new File(adocPath);
-
writeStringToFile(file, content.toString(),
"UTF-8");
-
}
-
-
private void writeStringToFile(File file, String content, String character) throws IOException {
-
if (!file.exists()) {
-
file.createNewFile();
-
}
-
FileOutputStream fos =
new FileOutputStream(file);
-
OutputStreamWriter osw =
new OutputStreamWriter(fos, character);
-
osw.write(content);
-
osw.flush();
-
}
-
-
private void fileAppend(StringBuilder content, String include, String title) {
-
File file =
new File(include);
-
if (file.exists()) {
-
content.append(title).append(System.getProperty(
"line.separator"));
-
content.append(
"include::").append(include).append(
"[]").append(System.getProperty(
"line.separator"));
-
}
-
}
很简单,也就是编写方法,创建文件,写入内容。
对啦,告诉你们我是怎么知道加那个目录的,当然是看asciidoctor的语法文档啦,在这里:点击打开链接
嗯,项目源码在此:拿去参考吧,直接就能运行:点击打开链接