1. 前言
现在文档大部分都是用swagger来生成的,但是springboot官网也提供了 spring rest doc 组件用于生成文档,因为java项目基本上都是用spring boot来创建的,所以个人倾向于spring rest doc.
2. 实现
spring rest doc 主要是基于unit单元测试实现的,添加依赖
testCompile 'org.junit.jupiter:junit-jupiter-api' testRuntime 'org.junit.jupiter:junit-jupiter-engine' testCompile 'org.springframework.restdocs:spring-restdocs-mockmvc' asciidoctor 'org.springframework.restdocs:spring-restdocs-asciidoctor'
添加asciidoctor配置,这块主要是配置生成snippets文件,
ext { snippetsDir = file('build/generated-snippets') } test { outputs.dir snippetsDir useJUnitPlatform() } asciidoctor { inputs.dir snippetsDir dependsOn test } bootJar { dependsOn asciidoctor from ("${asciidoctor.outputDir}/html5") { into 'static/docs' } }
添加单元测试
@SpringBootTest @ExtendWith({RestDocumentationExtension.class, SpringExtension.class}) public class BaseTestConfig { @Autowired protected WebApplicationContext context; protected ObjectMapper mapper = new ObjectMapper(); protected MockMvc mockMvc; @BeforeEach public void setUp(RestDocumentationContextProvider restDocumentation) { this.mockMvc = MockMvcBuilders.webAppContextSetup(context) .apply(documentationConfiguration(restDocumentation).uris().withPort(8090)).build(); } }
public class MyContractTest extends BaseTestConfig { @Test public void myContract() throws Exception { MyContract myContract = new MyContract(); myContract.setName("test1"); myContract.setUser("test2"); System.out.println(mapper.writeValueAsString(myContract)); this.mockMvc.perform(post("/contract").content(mapper.writeValueAsString(myContract)).contentType(MediaType.APPLICATION_JSON).accept(MediaType.APPLICATION_JSON)).andExpect(status().isOk()) .andDo(document("contract", requestFields(attributes(key("name").value("Fields for user creation"),key("user").value("Fields for user creation")) ,fieldWithPath("name").description("The user's name") .attributes(key("constraints") .value("Must not be null. Must not be empty")), fieldWithPath("user").description("The user's name") .attributes(key("constraints") .value("Must not be null. Must not be empty"))), responseFields(fieldWithPath("resultCode").description("状态")))); } }
看红色的document方法,这个会在打包的时候这个路径build\generated-snippets\contract生成contract的snippets片段
controller类是
@RestController public class ContractController { @PostMapping("/contract") public Map<String, String> postContact(@RequestBody MyContract mycontract) { System.out.println("Accepted mycontract"); return Collections.singletonMap("resultCode", "0"); } }
执行命令前 我们需要创建模板文件,在这个目录下src/docs/asciidoc/contract.adoc创建contract.adoc文件
= AsciiDoc Writer's Guide Doc Writer <doc.writer@asciidoctor.org> v1.0, 2013-08-01 :toc: left :toc-title: 模块 t1 ::: t2 test2:: t1 == 标题1 test1:: include::{snippets}/contract/http-request.adoc[] include::{snippets}/contract/request-body.adoc[] include::{snippets}/contract/request-fields.adoc[] == 标题2 include::{snippets}/contract/http-response.adoc[] include::{snippets}/contract/response-body.adoc[] include::{snippets}/contract/response-fields.adoc[] === test2 include::{snippets}/contract/httpie-request.adoc[] .... This is code; ....
然后运行下面这个命令,asciidoctor会根据上面创建的contract.adoc生成html文件,通过include引入adoc即可include::{snippets}/contract/http-request.adoc[].详情参阅官方文档
我们就可以发现
\build\asciidoc\html5 在这个目录下生成了 html文件
打开后就显示出了文档界面,需要写出漂亮的界面还要学习asciidoc文档的语法