上一篇中,咱們介紹了基本的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...