Spring REST Docs 构建java项目文档

最近因为项目中需要编写接口文档,原来用的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
							</outputDirectory>
							<resources>
								<resource>
									<directory>
										${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文档)。例子如下:

== hello 接口
.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[]

== hello2 接口
.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的语法文档啦,在这里:点击打开链接

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

  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值