上一篇中,咱们介绍了基本的API文档的生成方法,并最后成功的发布为html
文件。html
本节接上篇内容,进行文件的自动拼接,而且在出具API文件时,自动加入请求参数、主体的相关信息。html5
本文使用工具:java
springFoxgit
传送门: SpringFox官方文档
咱们此时,修改测试代码片断的接拼方式,因此删除原插件的配置信息。github
<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>2.0.1.RELEASE</version> </dependency> </dependencies> </plugin>
<repositories> <repository> <id>jcenter-snapshots</id> <name>jcenter</name> <url>http://oss.jfrog.org/artifactory/oss-snapshot-local/</url> </repository> </repositories> <dependency> <groupId>io.springfox</groupId> <artifactId>springfox-swagger2</artifactId> <version>2.9.0</version> </dependency> <dependency> <groupId>io.springfox</groupId> <artifactId>springfox-swagger-ui</artifactId> <version>2.9.0</version> </dependency> <dependency> <groupId>io.springfox</groupId> <artifactId>springfox-data-rest</artifactId> <version>2.9.0</version> </dependency> <dependency> <groupId>io.springfox</groupId> <artifactId>springfox-bean-validators</artifactId> <version>2.9.0</version> </dependency>
注意 加入到 pom.xml
中的相应标签中。其中repositories
为一级标签。即repositories
标签的父级为<project>
。web
新建SwaggerConfig
.(注意,该文件应该位于项目启动文件的同级或下级文件夹)spring
package com.mengyunzhi.check_apply_online.config; import org.springframework.context.annotation.Configuration; import org.springframework.web.servlet.config.annotation.WebMvcConfigurer; import springfox.documentation.swagger2.annotations.EnableSwagger2; @EnableSwagger2 // 启用Swagger2 @Configuration // 代表这是个配置文件,Spring在启动时,须要对本文件进行扫描 public class SwaggerConfig implements WebMvcConfigurer { }
启动项目,访问http://localhost:8080/swagger-ui.html
, 将显示如下界面。apache
加入Swagger
的相关注解后,会对应的生成中文说明。好比:json
package com.mengyunzhi.check_apply_online.controller; import com.mengyunzhi.check_apply_online.entity.DanWei; import com.mengyunzhi.check_apply_online.service.DanWeiService; import io.swagger.annotations.Api; import io.swagger.annotations.ApiOperation; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.security.core.Authentication; import org.springframework.security.core.context.SecurityContextHolder; import org.springframework.security.web.authentication.logout.SecurityContextLogoutHandler; import org.springframework.web.bind.annotation.*; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import java.security.Principal; @RestController @RequestMapping("/DanWei") @Api(value = "/DanWei", description = "单位") public class DanWeiController { private final static Logger logger = LoggerFactory.getLogger(DanWeiController.class); @Autowired DanWeiService danWeiService; @GetMapping("/login") @ApiOperation(value = "登陆", nickname = "其实登陆不限地址,任意地址都可以登陆。") public DanWei login(Principal user) { DanWei currentLoginDanWei = danWeiService.getCurrentLoginDanWei(); return currentLoginDanWei; } @GetMapping("/logout") @ApiOperation(value = "logout 注销", nickname = "DanWei_logout", notes = "参考资料:http://docs.spring.io/spring-security/site/docs/current/apidocs/org/springframework/security/web/authentication/logout/SecurityContextLogoutHandler.html") public void logout(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse) { logger.info("-----------------注销----------------"); danWeiService.setCurrentLoginDanWei(null); // 获取当前认证信息 Authentication authentication = SecurityContextHolder.getContext().getAuthentication(); // 若是存在认证信息则调用注销操做 if (null != authentication) { new SecurityContextLogoutHandler().logout(httpServletRequest, httpServletResponse, authentication); } return; } @PostMapping("/register") @ApiOperation(value = "注册新单位") public void save(@RequestBody DanWei danWei) { danWeiService.save(danWei); } }
则生成的中文说明以下:segmentfault
Swigger
支持自定义文件,便可以对html
的标题等信息进行定制。下面给出示例:
package com.mengyunzhi.check_apply_online.config; import com.google.common.base.Predicates; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.ComponentScan; import org.springframework.context.annotation.Configuration; import org.springframework.web.servlet.config.annotation.ResourceHandlerRegistry; import org.springframework.web.servlet.config.annotation.WebMvcConfigurer; import springfox.documentation.annotations.ApiIgnore; import springfox.documentation.builders.ApiInfoBuilder; import springfox.documentation.builders.PathSelectors; import springfox.documentation.service.ApiInfo; import springfox.documentation.service.Contact; import springfox.documentation.spi.DocumentationType; import springfox.documentation.spring.web.plugins.Docket; import springfox.documentation.swagger2.annotations.EnableSwagger2; @EnableSwagger2 // 启用Swagger2 @Configuration // 代表这是个配置文件,Spring在启动时,须要对本文件进行扫描 @ComponentScan(basePackageClasses = com.mengyunzhi.check_apply_online.controller.DanWeiController.class) public class SwaggerConfig implements WebMvcConfigurer { private static final Logger logger = LoggerFactory.getLogger(SwaggerConfig.class); /** * 建立Docket,写用配置信息 * @return */ @Bean public Docket api() { return new Docket(DocumentationType.SWAGGER_2) .apiInfo(this.apiInfo()) .select() // 加入除'error'外的全部请求信息 .paths(Predicates.and(PathSelectors.ant("/**"), Predicates.not(PathSelectors.ant("/error")))) .build() // 忽略的参数类型(ApiIgnore注解的字段) .ignoredParameterTypes(ApiIgnore.class) .enableUrlTemplating(true); } /** * 返回一个带有项目设置信息的ApiInfoBuilder * @return */ private ApiInfo apiInfo() { return new ApiInfoBuilder() .title("网上送检系统API") .description("为检定软件提供网上送检的支持") .contact(new Contact("panjie", "http://www.mengyunzhi.com", "3792535@qq.com")) .license("Apache 2.0") .licenseUrl("http://www.apache.org/licenses/LICENSE-2.0.html") .version("1.0.0") .build(); } }
则再次启动时,将使用咱们自定义的配置设置标题等信息。
swigger
的优势是能够获取到全部的控制器及方法,而且可以按列表的形式展示出来。 Spring REST Docs
的优势是只能够将测试数据直接展示给前台的用户。本节将阐述如何将两者结合起来使用。
<!--jcenter仓库插件地址 (必须有,否则有些包下载不到。。。)--> <pluginRepositories> <pluginRepository> <id>jcenter</id> <name>jcenter maven</name> <url>http://jcenter.bintray.com</url> </pluginRepository> </pluginRepositories> <properties> <!-- 其它配置信息--> <!--swgger2markup 配置信息--> <swagger2markup.version>1.2.0</swagger2markup.version> <asciidoctor.input.directory>${project.basedir}/src/main/asciidoc</asciidoctor.input.directory> <swagger.output.dir>${project.build.directory}/swagger</swagger.output.dir> <swagger.snippetOutput.dir>${project.build.directory}/generated-snippets</swagger.snippetOutput.dir> <generated.asciidoc.directory>${project.build.directory}/asciidoc/generated</generated.asciidoc.directory> <asciidoctor.html.output.directory>${project.build.directory}/asciidoc/html</asciidoctor.html.output.directory> <asciidoctor.pdf.output.directory>${project.build.directory}/asciidoc/pdf</asciidoctor.pdf.output.directory> <swagger.input>${swagger.output.dir}/swagger.json</swagger.input> </properties> <dependency> <groupId>io.springfox</groupId> <artifactId>springfox-staticdocs</artifactId> <version>2.4.0</version> </dependency> <dependency> <groupId>io.github.robwin</groupId> <artifactId>assertj-swagger</artifactId> <version>0.2.0</version> <scope>test</scope> </dependency> <dependency> <groupId>io.github.swagger2markup</groupId> <artifactId>swagger2markup-spring-restdocs-ext</artifactId> <version>${swagger2markup.version}</version> <scope>test</scope> </dependency> <plugin> <groupId>org.apache.maven.plugins</groupId> <artifactId>maven-surefire-plugin</artifactId> <configuration> <systemPropertyVariables> <!--设置变量信息--> <io.springfox.staticdocs.outputDir>${swagger.output.dir}</io.springfox.staticdocs.outputDir> <io.springfox.staticdocs.snippetsOutputDir>${swagger.snippetOutput.dir}</io.springfox.staticdocs.snippetsOutputDir> </systemPropertyVariables> </configuration> </plugin> <!-- 首先,生成asciidoc(.adoc) --> <plugin> <groupId>io.github.swagger2markup</groupId> <artifactId>swagger2markup-maven-plugin</artifactId> <version>${swagger2markup.version}</version> <dependencies> <dependency> <groupId>io.github.swagger2markup</groupId> <artifactId>swagger2markup-import-files-ext</artifactId> <version>${swagger2markup.version}</version> </dependency> <dependency> <groupId>io.github.swagger2markup</groupId> <artifactId>swagger2markup-spring-restdocs-ext</artifactId> <version>${swagger2markup.version}</version> </dependency> </dependencies> <configuration> <swaggerInput>${swagger.input}</swaggerInput> <outputDir>${generated.asciidoc.directory}</outputDir> <config> <swagger2markup.markupLanguage>ASCIIDOC</swagger2markup.markupLanguage> <swagger2markup.pathsGroupedBy>TAGS</swagger2markup.pathsGroupedBy> <swagger2markup.extensions.dynamicOverview.contentPath>${project.basedir}/src/main/asciidoc/extensions/overview</swagger2markup.extensions.dynamicOverview.contentPath> <swagger2markup.extensions.dynamicDefinitions.contentPath>${project.basedir}/src/main/asciidoc/extensions/definitions</swagger2markup.extensions.dynamicDefinitions.contentPath> <swagger2markup.extensions.dynamicPaths.contentPath>${project.basedir}/src/main/asciidoc/extensions/paths</swagger2markup.extensions.dynamicPaths.contentPath> <swagger2markup.extensions.dynamicSecurity.contentPath>${project.basedir}src/main/asciidoc/extensions/security/</swagger2markup.extensions.dynamicSecurity.contentPath> <swagger2markup.extensions.springRestDocs.snippetBaseUri>${swagger.snippetOutput.dir}</swagger2markup.extensions.springRestDocs.snippetBaseUri> <swagger2markup.extensions.springRestDocs.defaultSnippets>true</swagger2markup.extensions.springRestDocs.defaultSnippets> </config> </configuration> <executions> <execution> <phase>test</phase> <goals> <goal>convertSwagger2markup</goal> </goals> </execution> </executions> </plugin> <!-- 而后,使用Asciidoctor(前面在spring rest docs时已安装,在这须要加部分依赖)将.adoc转成pdf和html --> <plugin> <groupId>org.asciidoctor</groupId> <artifactId>asciidoctor-maven-plugin</artifactId> <version>1.5.3</version> <!-- PDF依赖 --> <dependencies> <dependency> <groupId>org.asciidoctor</groupId> <artifactId>asciidoctorj-pdf</artifactId> <version>1.5.0-alpha.10.1</version> </dependency> <dependency> <groupId>org.jruby</groupId> <artifactId>jruby-complete</artifactId> <version>1.7.21</version> </dependency> </dependencies> <!-- 生成文件时的配置信息 --> <configuration> <sourceDirectory>${asciidoctor.input.directory}</sourceDirectory> <sourceDocumentName>index.adoc</sourceDocumentName> <attributes> <doctype>book</doctype> <toc>left</toc> <toclevels>3</toclevels> <numbered></numbered> <hardbreaks></hardbreaks> <sectlinks></sectlinks> <sectanchors></sectanchors> <generated>${generated.asciidoc.directory}</generated> </attributes> </configuration> <!-- Since each execution can only handle one backend, run separate executions for each desired output type --> <executions> <!--生成html--> <execution> <id>output-html</id> <phase>test</phase> <goals> <goal>process-asciidoc</goal> </goals> <configuration> <backend>html5</backend> <outputDirectory>${asciidoctor.html.output.directory}</outputDirectory> </configuration> </execution> <!--生成pdf--> <execution> <id>output-pdf</id> <phase>test</phase> <goals> <goal>process-asciidoc</goal> </goals> <configuration> <backend>pdf</backend> <outputDirectory>${asciidoctor.pdf.output.directory}</outputDirectory> </configuration> </execution> </executions> </plugin>
执行mvn package -Dmaven.test.skip=true
跳过测试,直接进行打包。第一次会下载插件,时间长短看网速。
最终将获得以下错误:
即target
下的swagger.json
未生成。该文件即上个章节中的查看/v2/api-docs
提到的json
文件。下面,咱们增长一个单元测试文件,运行其的做用是访问/v2/api-docs
,抓取返回的内容,并存储为:swagger.json
文件。
package com.mengyunzhi.check_apply_online.controller; import org.junit.Test; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.http.MediaType; 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; public class SwaggerTest extends ControllerTest { private final static Logger logger = LoggerFactory.getLogger(SwaggerTest.class); @Test public void createSwaggerJson() throws Exception { logger.info("------ 获取用于生成自动文档的swagger.json文件 ------"); String swaggerJson = this.mockMvc.perform(get("/v2/api-docs").accept(MediaType.APPLICATION_JSON)) .andExpect(status().isOk()).andReturn().getResponse().getContentAsString(); // 对应pom.xml中 <systemPropertyVariables> 设置的属性值 // String outputDir = System.getProperty("io.springfox.staticdocs.outputDir"); String outputDir = "target/swagger"; Files.createDirectories(Paths.get(outputDir)); try (BufferedWriter writer = Files.newBufferedWriter(Paths.get(outputDir, "swagger.json"), StandardCharsets.UTF_8)) { writer.write(swaggerJson); } return; } }
执行单元测试,将获得target/swagger/swagger.json
, 同时,咱们修改src/main/asciidoc/index.adoc
文件,使其包含插件自动生成的四个文件。
include::{generated}/overview.adoc[] include::{generated}/paths.adoc[] include::{generated}/security.adoc[] include::{generated}/definitions.adoc[]
最后,咱们再次执行mvn package -Dmaven.test.skip=true
将获得如下文件:
其中html
文件夹,为生成的html
格式的API文档。pdf
文件夹中为生成的pdf
文档。咱们进行html
文件夹,更能够浏览生成的html
文档了。
咱们swagger的HTML文件也有了,spring rest docs的测试文件也有了,那么如何进行关联呢?
很简单,咱们只须要为控制器的相应方法与测试时生成的片断名称起想同的名字就能够了。
好比:
@PostMapping("/register") @ApiOperation(value = "注册新单位", nickname = "DanWei_register") public void save(@RequestBody DanWei danWei) { danWeiService.save(danWei); }
测试文件:
@Test public void registerTest() throws Exception { String url = "/DanWei/register"; this.mockMvc.perform(MockMvcRequestBuilders .post(url) .contentType(MediaType.APPLICATION_JSON_UTF8) .content("{}")) .andExpect(MockMvcResultMatchers.status().isOk()) .andDo(MockMvcRestDocumentation.document("DanWei_register")); }
执行mvn package
后,相关的测试片断,则自动加入到了相应的位置上。
其实了除了起一个相同的之外,还取于这个配置:<swagger.snippetOutput.dir>${project.build.directory}/generated-snippets</swagger.snippetOutput.dir>
,是它告诉了Swagger
:spring rest docs
生成的测试代码片断在的位置。
咱们能够修改src/main/asciidoc/index.adoc
来达到更改生成的html
内容的目的。好比,咱们加入一些测试的说明。
include::{generated}/overview.adoc[] == 说明 当前版本:1.0 === 开发环境 java1.8 + maven3.3 === 测试用户 用户名: user1, 密码: user1 include::{generated}/paths.adoc[] include::{generated}/security.adoc[] include::{generated}/definitions.adoc[]
则从新mvn package
后,将生成以下html
:
在本节中,咱们主要使用了一个插件进行了文档的自动生成。插件大概替咱们作了以下的事情:
swagger.json
来生成.adoc
src/main/asciidoc/index.adoc
生成html
和pdf
.其实,为了给swagger
提供可用的json
,咱们写了单元测试文件。
在下一节中,咱们将阐述如何使用自动测试机器人结合github
,实现自动发布API文档。
参考非官方教程:
https://leongfeng.github.io/2...