SpringBoot 內建Swagger2自動生成文檔和導出成靜态檔案
目錄
- 簡介
-
內建Swagger2
2.1 導入Swagger庫
2.2 配置Swagger基本資訊
2.3 使用Swagger注解
2.4 文檔效果圖
- 常用注解介紹
-
Swagger2文檔導出成pdf
4.1 生成pdf的格式
4.2 生成靜态文檔步驟
4.2.1 配置gradle
4.2.2 生成swagger json檔案
4.2.3 生成swagger markdown檔案
4.2.4 markdown轉pdf
- 今天是五一的一天,武漢因為疫情不能随意出去,寫篇部落格打發時間。今天介紹一款非常熱門的API開發工具-----Swagger,其遵循OpenAPI規範。使用簡單、可以自動化生成API文檔、可以模拟HTTP接口請求等強大的功能。它可以節省我們的開發時間,進而提高工作效率。不僅如此,Swagger還支援生成靜态文檔的功能,可以用來傳遞一些對文檔要求并不是很高的客戶。
- SpringBoot 內建Swagger也非常簡單,同樣也是簡單的三個步驟:導包、配置和使用。
swaggerVersion = '2.6.1'
compile("io.springfox:springfox-swagger2:${swaggerVersion}")
compile("io.springfox:springfox-swagger-ui:${swaggerVersion}")
這兩個是swagger自動生成文檔需要的庫。若需要生成靜态文檔,還需要導入其他額外的庫。
package com.itdragon.server.config
import org.springframework.context.annotation.Bean
import org.springframework.context.annotation.Configuration
import springfox.documentation.builders.ApiInfoBuilder
import springfox.documentation.builders.PathSelectors
import springfox.documentation.builders.RequestHandlerSelectors
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
@Configuration
class Swagger2Config {
@Bean
fun createRestApi(): Docket {
return Docket(DocumentationType.SWAGGER_2) // 指定生成的文檔的類型是Swagger2
.apiInfo(itDragonApiInfo()) // 配置文檔頁面的基本資訊内容
.select()
// 指定掃描包路徑
.apis(RequestHandlerSelectors.basePackage("com.itdragon.server.api.rest"))
.paths(PathSelectors.any())
.build()
}
private fun itDragonApiInfo(): ApiInfo {
return ApiInfoBuilder()
.title("ITDragon Swagger API Document")
.description("ITDragon Swagger Description...")
.contact(Contact("ITDragon", "https://www.cnblogs.com/itdragon/", "[email protected]"))
.version("0.1")
.description("ITDragon SpringBoot Swagger API INFO")
.build()
}
}
1)建立Swagger2的配置類,分别用注解@Configuration和@EnableSwagger2修飾。
2)配置自動生成文檔的類型、頁面的基本資訊和掃描包的路徑。
package com.itdragon.server.api.rest
import io.swagger.annotations.*
import org.springframework.format.annotation.DateTimeFormat
import org.springframework.http.ResponseEntity
import org.springframework.web.bind.annotation.*
import springfox.documentation.annotations.ApiIgnore
import java.util.*
import javax.servlet.http.HttpServletResponse
@Api(tags = ["SwaggerDemo"])
@RestController
@RequestMapping("/itdragon")
class ITDragonSwagger2Controller {
@ApiOperation("方法說明", notes = "通過ApiOperation注解修飾方法,對方法做詳細介紹。若不使用,Swagger會以函數名作為描述。", httpMethod = "GET")
@GetMapping("/ApiOperation/info")
fun getITDragonApiOperationInfo(@RequestParam("ids") ids: String): ResponseEntity<Unit> {
return ResponseEntity.ok(Unit)
}
@ApiOperation("參數說明", notes = "通過ApiImplicitParams注解修飾參數,對參數做詳細介紹。若不适用,")
@ApiImplicitParams(value = [
ApiImplicitParam(name = "deviceIds", value = "裝置ID集合,用逗号區分", required = true, dataType = "String", paramType = "query"),
ApiImplicitParam(name = "search", value = "查詢字段")])
@GetMapping("/ApiImplicitParams/info")
fun getITDragonApiImplicitParamsInfo(@RequestParam("deviceIds") deviceIds: String,
@RequestParam("search") search: String,
@ApiIgnore currentUser: String): ResponseEntity<Unit> {
return ResponseEntity.ok(Unit)
}
@ApiOperation("對象參數說明", notes = "")
@PostMapping("/ApiModel/info")
fun postITDragonApiModelInfo(@RequestBody itDragonCreateInfo: ITDragonCreateInfo) {
}
@GetMapping("/Native/info")
fun getITDragonNativeInfo(@RequestParam("active", required = false) active: Boolean?,
@RequestParam("search", required = false) search: String?,
@RequestParam("startTime", required = false) @DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss") startTime: Date?,
@RequestParam("endTime", required = false) @DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss") endTime: Date?,
@RequestParam("page", required = false, defaultValue = "1") page: Int = 1,
@RequestParam("size", required = false, defaultValue = "10") size: Int = 10): ResponseEntity<Unit> {
return ResponseEntity.ok(Unit)
}
@ApiModel("建立使用者模型")
class ITDragonCreateInfo {
@ApiModelProperty("使用者賬号,登入賬号")
var username: String? = null
var nikename: String? = null
1)使用注解@Api 修飾類,可以描述這個類的作用。實際使用過程中發現:若用中文描述會存在點不開單個接口詳情的問題。
2)使用注解@ApiOperation 修飾方法,可以描述這個方法的功能和注意事項。若不使用則用函數名作為方法功能。
3)使用注解@ApiImplicitParams 修飾方法,可以描述這個方法的參數的作用。若不使用則用參數名作為參數的作用。
4)使用注解@ApiModel 修飾實體類,可以描述這個類的功能。
5)使用注解@ApiModelProperty 修飾實體類的屬性,可以描述這個屬性的作用。
6)使用注解@ApiIgnore 修飾參數、方法和類,可以在自動生成文檔時對修飾的對象進行忽略。
小結:我ITDragon一般在需要有中文描述的場景下會使用這些注解。因為swagger很強大,即便是不使用注解,依然可以自動生成文檔。
- 注解 說明
ApiOperation 描述一個方法的作用和相關的提示資訊
ApiImplicitParams 描述一個方法的多個參數的作用、資料類型、等資訊
ApiIgnore 生成的文檔忽略被修飾的類、方法、參數
ApiModel 描述一個實體類的功能
ApiModelProperty 描述一個實體類屬性的作用
還有很多像@Api、@ApiParam、@ApiProperty這些注解,我ITDragon 覺得意義不是特别大。把更多的精力放在業務邏輯上。因為Swagger生成的文檔更适合團隊内部使用,内部人對文檔的要求并不是特别高。但是對于一些嚴格的客戶,文檔還是要重新寫。
我ITDragon 曾經按照網上的教程将swagger文檔生成markdown格式的靜态文檔,然後再通過Typora工具導出成pdf。雖然也支援導出成word文檔。但是word文檔的排版不好看。而且靜态文檔的最大缺陷就是實體類和接口是分開的。效果圖如下所示。
接口定義的部分:
實體類聲明的部分:
當然你也可以把實體類的資料拷貝到接口對應的位置。但是這個工作量也不小。
完整代碼可以點選文章位址的位址
buildscript {
ext {
springBootVersion = '2.0.6.RELEASE'
swaggerVersion = '2.6.1'
}
dependencies {
classpath("org.springframework.boot:spring-boot-gradle-plugin:${springBootVersion}")
classpath("com.benjaminsproule:swagger-gradle-plugin:1.0.7")
}
apply plugin: 'com.benjaminsproule.swagger'
swagger {
apiSource {
springmvc = true
locations = ["com.itdragon.server.api.rest"]
schemes = ["http", "https"]
host = "www.cnblogs.com/itdragon"
info {
title = "ITDragon Swagger2 API Document"
version = "0.1"
description = "API Document Description"
contact {
email = "[email protected]"
name = "ITDragon"
url = "https://www.cnblogs.com/itdragon/"
}
license {
url = "http://www.apache.org/licenses/LICENSE-2.0.html"
name = "Apache 2.0"
}
}
outputPath = "${project.rootDir}/generated/document.html"
swaggerDirectory = "${project.rootDir}/generated/swagger-ui"
attachSwaggerArtifact = true
}
dependencies {
/* swagger */
compile("io.swagger:swagger-annotations:1.5.21")
compile("io.springfox:springfox-swagger2:${swaggerVersion}")
compile("io.springfox:springfox-swagger-ui:${swaggerVersion}")
compile("io.springfox:springfox-staticdocs:${swaggerVersion}")
testCompile('org.springframework.restdocs:spring-restdocs-mockmvc:2.0.2.RELEASE')
在項目根目錄下,運作./gradlew generateSwaggerDocumentation 指令。
若成功,會在根目錄下生成:/generated/swagger-ui/swagger.json,且這個json檔案内容不為空。反之則失敗。
admin@DESKTOP-3 MINGW64 /d/daydayup/SpringBoot/spring-boot-swagger2 (master)
$ ./gradlew generateSwaggerDocumentation
Task :compileKotlin UP-TO-DATE
Task :compileJava NO-SOURCE
Task :processResources UP-TO-DATE
Task :classes UP-TO-DATE
Task :generateSwaggerDocumentation
BUILD SUCCESSFUL in 5s
3 actionable tasks: 1 executed, 2 up-to-date
注意:
1)若ApiImplicitParam 若沒有dataType或者paramType,則會導緻生成靜态文檔報錯> Unrecognized Type: [null]
在src目錄下建立testkotlincomitdragonserverITDragonGenerateDoc.kt 檔案,代碼内容如下:
package com.itdragon.server
import io.github.robwin.markup.builder.MarkupLanguage
import io.github.robwin.swagger2markup.Swagger2MarkupConverter
import org.junit.Test
class ITDragonGenerateDoc {
private val snippetDir = "/generated/snippets"
private val outputDir = "generated/swagger-ui"
/**
* 第一步:./gradlew generateSwaggerDocumentation
* 第二步:./gradlew test --tests *ITDragonGenerateDoc
*/
@Test
@Throws(Exception::class)
fun doIt() {
Swagger2MarkupConverter.from("$outputDir/swagger.json")
.withMarkupLanguage(MarkupLanguage.MARKDOWN)
.withExamples(snippetDir)
.build()
.intoFolder(outputDir)
}
同時在項目根目錄下運作./gradlew test --tests *ITDragonGenerateDoc 指令。
運作成功後會在/generated/swagger-ui/目錄下生成三個檔案,分别是:overview.md、definitions.md、paths.md檔案。
1)若指定 .withPathsGroupedBy(GroupBy.TAGS) 按照按tag排序,但是有的注解并沒有指定tag會報錯。
我們可以使用Typora工具,将markdown格式的檔案導出成pdf或者word檔案。
源碼位址:
https://github.com/ITDragonBlog/daydayup作者:ITDragon龍
原文位址
https://www.cnblogs.com/itdragon/p/12588010.html