当前位置: 代码迷 >> 综合 >> Spring REST Docs 构建java项目文档
  详细解决方案

Spring REST Docs 构建java项目文档

热度:58   发布时间:2024-01-15 23:47:11.0

转自:https://blog.csdn.net/seanxwq/article/details/78064599

最近因为项目中需要编写接口文档,原来用的swagger结合现有项目问题比较多,且没有直观的目录(不知道swagger是否有左边栏目录这样的形式,没去细查),配合前端和测试使用时,他们抱怨比较多,所以摒弃了swagger之后,找到了spring rest docs, 结合官方文档和网上查到的资料,成功生成了接口文档。样例如下:

接口文档样例

spring rest docs的使用其实就是在你现有的spring mvc或spring boot的项目上,配置生成文档的依赖包,然后编写接口单元测试,编写adoc配置文件,最后打包自动生成html接口文档的过程。根据这个步骤一步步操作:

1、配置依赖:


  
  1. <dependency>
  2. <groupId>org.springframework.restdocs </groupId>
  3. <artifactId>spring-restdocs-mockmvc </artifactId>
  4. <scope>test </scope>
  5. </dependency>

  
  1. <build>
  2. <plugins>
  3. <plugin>
  4. <groupId>org.springframework.boot </groupId>
  5. <artifactId>spring-boot-maven-plugin </artifactId>
  6. </plugin>
  7. <plugin>
  8. <groupId>org.asciidoctor </groupId>
  9. <artifactId>asciidoctor-maven-plugin </artifactId>
  10. <version>1.5.3 </version>
  11. <executions>
  12. <execution>
  13. <id>generate-docs </id>
  14. <phase>prepare-package </phase>
  15. <goals>
  16. <goal>process-asciidoc </goal>
  17. </goals>
  18. <configuration>
  19. <backend>html </backend>
  20. <doctype>book </doctype>
  21. </configuration>
  22. </execution>
  23. </executions>
  24. <dependencies>
  25. <dependency>
  26. <groupId>org.springframework.restdocs </groupId>
  27. <artifactId>spring-restdocs-asciidoctor </artifactId>
  28. <version>1.2.1.RELEASE </version>
  29. </dependency>
  30. </dependencies>
  31. </plugin>
  32. <plugin>
  33. <artifactId>maven-resources-plugin </artifactId>
  34. <version>2.7 </version>
  35. <executions>
  36. <execution>
  37. <id>copy-resources </id>
  38. <phase>prepare-package </phase>
  39. <goals>
  40. <goal>copy-resources </goal>
  41. </goals>
  42. <configuration>
  43. <outputDirectory>
  44. ${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">&lt;/<span class="hljs-name">outputDirectory</span>&gt;</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">&lt;<span class="hljs-name">resources</span>&gt;</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">&lt;<span class="hljs-name">resource</span>&gt;</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">&lt;<span class="hljs-name">directory</span>&gt;</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
  45. </directory>
  46. </resource>
  47. </resources>
  48. </configuration>
  49. </execution>
  50. </executions>
  51. </plugin>
  52. </plugins>
  53. </build>
2、编写接口测试

我们通过mock进行接口测试编写,测试类属性配置及单测前的before方法:


  
  1. @Rule
  2. public JUnitRestDocumentation restDocumentation = new JUnitRestDocumentation( "target/generated-snippets"); //生成的adoc文件导出目录
  3. private MockMvc mockMvc;
  4. @Autowired
  5. private WebApplicationContext context;
  6. @Before
  7. public void setUp() {
  8. this.mockMvc = MockMvcBuilders.webAppContextSetup( this.context)
  9. .apply(documentationConfiguration( this.restDocumentation))
  10. // .alwaysDo(document("{method-name}/{step}/"))
  11. .build();
  12. }
单测例子(与普通的mock测试多了红色标注的部分,语法什么的我就不在这里讲解了,要想写出来,肯定要看官方文档: 点击打开链接,如果不想看英文,看这个博客也可以: 点击打开链接,不过,还是强烈推荐看官方文档):


  
  1. @Test
  2. public void contextLoads() throws Exception {
  3. this.mockMvc.perform(get( "/hello?page=2&per_page=100").accept(MediaType.APPLICATION_JSON).header( "Authorization", "Basic dXNlcjpzZWNyZXQ="))
  4. .andDo(print()).andExpect(status().isOk())
  5. .andDo(document( "hello 接口", //这个identity不同的单测需要不同,否则其他的测试会覆盖现有的,最后文档里只生成一个接口说明
  6. requestHeaders(
  7. headerWithName( "Authorization").description(
  8. "Basic auth credentials")),
  9. requestParameters(
  10. parameterWithName( "page").description( "The page to retrieve"),
  11. parameterWithName( "per_page").description( "Entries per page")
  12. )));
  13. }
3、编写adoc配置文件

在maven项目标准结构下,src/main下新建asciidoc目录,并建一个.adoc为结尾的文件(到时候打包时,会根据asciidoc目录下的所有.adoc文件生成过个对应文件名的html文档)。例子如下:


  
  1. <span style= "color:#ff6666;">== hello 接口</span>
  2. .http- request
  3. include::D:\ideaworkspace\restdoc\target\generated-snippets\hello 接口\http- request.adoc[]
  4. . request-headers 请求头说明
  5. include::D:\ideaworkspace\restdoc\target\generated-snippets\hello 接口\ request-headers.adoc[]
  6. . request-parameters 请求参数说明
  7. include::D:\ideaworkspace\restdoc\target\generated-snippets\hello 接口\ request-parameters.adoc[]
  8. .http- response
  9. include::D:\ideaworkspace\restdoc\target\generated-snippets\hello 接口\http- response.adoc[]
  10. <span style= "color:#ff6666;">== hello2 接口</span>
  11. .http- request
  12. include::D:\ideaworkspace\restdoc\target\generated-snippets\hello2 接口\http- request.adoc[]
  13. .http- response
  14. include::D:\ideaworkspace\restdoc\target\generated-snippets\hello2 接口\http- response.adoc[]
4、ok,最后用maven打包项目,跑完之后,就可以在target/generated-docs下看到你的文件了,直接双击打开,就能看到生成的文档。

以上是根据官网文档,就可以导出一个接口文档。但是,并没有左边栏的目录,而且写一个单测就要在.adoc文件里添加include关键字导入新生成的接口内容很麻烦,怎么办呢?

首先,左边栏目录或右边栏目录,或直接在文档最开头添加目录我们只需要在.adoc文件开头添加如下内容:


  
  1. = 接口文档
  2. v1 .0, 2017 -09 -22
  3. :toc: left
它会自动根据你文件下发的接口配置来定义目录,前面第3点列出的那个配置红色部分就是接口的引用配置。是不是很简单,配置完之后,就能生成和我文档最开头那张图片的样子了。

然后解决每写一个接口测试就要在.adoc文件里添加include的问题:

我们编写.adoc文件生成功能,方法如下(参考了:点击打开链接):


  
  1. @Test
  2. public void adocBuild() throws IOException {
  3. String appDir = System.getProperty( "user.dir");
  4. String adocPath = appDir + "\src\main\asciidoc\hello.adoc";
  5. StringBuilder content = new StringBuilder();
  6. content.append( "include::" + appDir + "\src\main\asciidoc\preview.adoc[]").append(System.getProperty( "line.separator")).append(System.getProperty( "line.separator"));
  7. File apidirs = new File(appDir + "\target\generated-snippets");
  8. for (File apidir : apidirs.listFiles()) {
  9. String apiName = apidir.getName();
  10. content.append( "== " + apiName + System.getProperty( "line.separator"));
  11. fileAppend(content, apidir + "\http-request.adoc", ".http-request");
  12. fileAppend(content, apidir + "\request-headers.adoc", ".request-headers 请求头说明");
  13. fileAppend(content, apidir + "\request-parameters.adoc", ".request-parameters 请求参数说明");
  14. fileAppend(content, apidir + "\request-body.adoc", ".request-body 请求体说明");
  15. fileAppend(content, apidir + "\http-response.adoc", ".http-response");
  16. fileAppend(content, apidir + "\response-fields.adoc", ".response-fields 返回值说明");
  17. content.append(System.getProperty( "line.separator"));
  18. }
  19. // System.out.println(adocPath);
  20. // System.out.println(content);
  21. File file = new File(adocPath);
  22. writeStringToFile(file, content.toString(), "UTF-8");
  23. }
  24. private void writeStringToFile(File file, String content, String character) throws IOException {
  25. if (!file.exists()) {
  26. file.createNewFile();
  27. }
  28. FileOutputStream fos = new FileOutputStream(file);
  29. OutputStreamWriter osw = new OutputStreamWriter(fos, character);
  30. osw.write(content);
  31. osw.flush();
  32. }
  33. private void fileAppend(StringBuilder content, String include, String title) {
  34. File file = new File(include);
  35. if (file.exists()) {
  36. content.append(title).append(System.getProperty( "line.separator"));
  37. content.append( "include::").append(include).append( "[]").append(System.getProperty( "line.separator"));
  38. }
  39. }
很简单,也就是编写方法,创建文件,写入内容。

对啦,告诉你们我是怎么知道加那个目录的,当然是看asciidoctor的语法文档啦,在这里:点击打开链接

嗯,项目源码在此:拿去参考吧,直接就能运行:点击打开链接

  相关解决方案