這篇文章資料來自于網絡,對部分知識整理,這里只是記錄一下,僅供參考
為什么要用 Swagger
????????Swagger 的核心思想是通過定義和描述 API 的規范、結構和交互方式,以提高 API 的可讀性、可靠性和易用性,同時降低 API 開發的難度和開發者之間的溝通成本。
????????這里我采用了 Swagger3.0(Open API 3.0)的方式集成到 SpringBoot。springfox-boot-start 和 springfox-swagger2 都是基于 Swagger2.x 的。
????????這里將介紹 springdoc-openapi-ui,它是 SpringBoot 基于 Open API 3.0(Swagger3.0)
SpringFox 與 Swagger 的關系
????????Springfox 是一套可以幫助 Java 開發者自動生成 API 文檔的工具,它是基于 Swagger 2.x 基礎上開發的。
????????除了集成 Swagger 2.x,Springfox 還提供了一些額外功能,例如自定義 Swagger 文檔、API 版本控制、請求驗證等等。
但是隨著時間的推移,Swagger2.x 終究成為歷史,所以我們可以看出 springfox-boot-starter 的坐標從 3.0.0 版本(2020 年 7 月 14 日)開始就一直沒有更新; 也得注意的是 springfox-swagger2 坐標和 springfox-boot-start 是一樣的,但 springfox-boot-start 只有 3.0.0 版本。這里我就不在使用 Swagger2.x 版本
添加依賴
由于篇幅原因,其他web項目相關依賴這里就不一一貼出來了。
第一個依賴是必須的,而且版本必須大于2.0.0
<dependency><groupId>org.springdoc</groupId><artifactId>springdoc-openapi-starter-webmvc-ui</artifactId><version>2.2.0</version> </dependency> <dependency><groupId>org.springdoc</groupId><artifactId>springdoc-openapi-starter-webmvc-api</artifactId><version>2.2.0</version> </dependency>
注:
????????我們這里使用的是jdk17+springboot3.5.0
?環境,原來swagger
的V2
和V3
都不能用了,小伙伴們一定更要注意這兒
????????如果引入上面錯誤的依賴,項目啟動會報下面錯誤,這時候我們引入上面正確的依賴重新啟動項目即可
SpringDoc(推薦)
????????SpringDoc 對應坐標是 springdoc-openapi-ui,它是一個集成 Swagger UI 和 ReDoc 的接口文檔生成工具,在使用上與 springfox-boot-starter 類似,但提供了更為靈活、功能更加強大的工具。
????????其中除了可以生成 Swagger UI 風格的接口文檔,還提供了 ReDoc 的文檔渲染方式,可以自動注入 OpenAPI 規范的 JSON 描述文件,支持 OAuth2、JWT 等認證機制,并且支持全新的 OpenAPI 3.0 規范。
SpringBoot 3 集成 Swagger3.0
????????需要注意的是,我們一般不會選擇原生的 Swagger maven 坐標來集成 Swagger。而是通過 springdoc-openapi-ui 的 Maven 坐標。
????????它可以很好的和 Spring 或 SpringBoot 項目集成;這個坐標也被 Spring 社區廣泛支持和認可,并被認為是集成 Swagger UI 和 OpenAPI 規范的一個優秀選擇。
引入 Maven
在該示例中,我使用 Spring Boot 3.0.2 集成 Swagger 3.0。
????????springdoc-openapi-starter-webmvc-ui
:目前最新版本是 2.6.0,適用于 Spring Boot 3.x 和 Spring Framework 6。支持 Jakarta 命名空間(例如,jakarta.validation
),適合 Spring Boot 3 的 Jakarta EE 轉換。
<dependencies><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-web</artifactId></dependency><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-validation</artifactId></dependency><dependency><groupId>org.springdoc</groupId><artifactId>springdoc-openapi-starter-webmvc-ui</artifactId><version>2.6.0</version></dependency><dependency><groupId>org.projectlombok</groupId><artifactId>lombok</artifactId></dependency></dependencies>
配置 SwaggerOpenApiConfig
我們通過配置類的方式創建一個 OpenAPI 的 Bean 對象就可以創建 Swagger3.0 的文檔說明。
import io.swagger.v3.oas.models.ExternalDocumentation;
import io.swagger.v3.oas.models.OpenAPI;
import io.swagger.v3.oas.models.info.Info;
import io.swagger.v3.oas.models.info.License;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;@Configuration
public class Swagger3Config {@Beanpublic OpenAPI springShopOpenAPI() {return new OpenAPI().info(new Info().title("碼哥跳動 Swagger3 詳解").description("Swagger3 Spring Boot 3.0 application").version("v0.0.1").license(new License().name("Apache 2.0").url("http://springdoc.org"))).externalDocs(new ExternalDocumentation().description("swagger 3 詳解").url("https://springshop.wiki.github.org/docs"));}}
????????OpenAPI 對象是 Swagger 中的核心類之一,用于描述整個 API 的結構和元數據。
????????Swagger2 和 Swagger3 使用的是完全不同的兩套注解,所以原本使用 Swagger2 相關注解的代碼頁需要完全遷移,改為使用 Swagger3 的注解。
Swagger2 | Swagger3 |
---|---|
@Api | @Tag |
@ApiOperation | @Operation |
@ApiImplicitParams | @Parameters |
@ApiImplicitParam | @Parameter |
@ApiModel | @Schema |
@ApiModelProperty | @Schema |
@ApiResponses | @ApiResponses |
@ApiResponse | @ApiResponse |
@ApiIgnore | @Hidden 或者 其他注解的 hidden = true 屬性 |
配置文件
????????通過以下配置來控制 swagger 的開關和訪問地址:WEB 界面的顯示基于解析 JSON 接口返回的結果, 如果 api-docs 關閉, swagger-ui 即使 enable 也無法使用。
server:port: 8013spring:application:name: magebyte-swaggerspringdoc:api-docs:enabled: true # 開啟OpenApi接口path: /v3/api-docs # 自定義路徑,默認為 "/v3/api-docs"swagger-ui:enabled: true # 開啟swagger界面,依賴OpenApi,需要OpenApi同時開啟path: /swagger-ui.html # 自定義路徑,默認為"/swagger-ui/index.html"# Packages to include,多個用 , 分割packagesToScan: zero.magebyte.magebyte.swagger.controller
需要注意的是,packagesToScan 用于指定 Controller 接口包路徑。
@Schema
Swagger3 用 @Schema 注解對象和字段, 以及接口中的參數類型。
@Setter
@Getter
@Schema(description = "響應返回數據對象")
public class Result<T> implements Serializable {@Schema(title = "code",description = "響應碼",format = "int32",requiredMode = Schema.RequiredMode.REQUIRED)private Integer code;@Schema(title = "msg",description = "響應信息",accessMode = Schema.AccessMode.READ_ONLY,example = "成功或失敗",requiredMode = Schema.RequiredMode.REQUIRED)private String message;@Schema(title = "data", description = "響應數據", accessMode = Schema.AccessMode.READ_ONLY)private T data;
}
返回對象定義
@Data
@AllArgsConstructor
@Schema(title = "學生模型VO", description = "響應視圖學生模型VO")
public class StudentVO implements Serializable {@Schema(name = "學生ID", description = "學生ID屬性", format = "int64", example = "1")private Long id; // 學生ID@Schema(name = "學生姓名", description = "學生姓名屬性", example = "jack")private String name; // 學生姓名@Schema(name = "學生年齡", description = "學生年齡屬性", format = "int32", example = "24")private Integer age; // 學生年齡@Schema(name = "學生地址", description = "學生地址屬性", example = "安徽合肥")private String address; // 學生地址@Schema(name = "學生分數", description = "學生分數屬性", format = "double", example = "55.50")private Double fraction; // 學生分數@Schema(name = "學生愛好", description = "學生愛好屬性(List類型)",type = "array", example = "[\"玩\", \"寫字\"]")private List<String> likes; // 學生愛好
}
@Paramete
@Parameter 注解用于描述方法參數。如果不希望顯示某個參數, 用@Parameter(hidden = true)
修飾。
@Parameters({@Parameter(name = "currentPage", description = "當前頁碼", required = true),@Parameter(name = "size", description = "當前頁大小", example = "10"),@Parameter(name = "queryUser", description = "用戶查詢條件")
})
Controller 接口定義
啟動項目,打開鏈接:http://localhost:8013/swagger-ui/index.html
@RestController
@RequestMapping("/students")
@Tag(name = "StudentControllerAPI", description = "學生控制器接口", externalDocs = @ExternalDocumentation(description = "這是一個接口文檔介紹"))
public class StudentController {@Operation(summary = "根據Id查詢學生信息", description = "根據ID查詢學生信息,并返回響應結果信息",parameters = {@Parameter(name = "id", description = "學生ID", required = true, example = "1")},responses = {@ApiResponse(responseCode = "200",description = "響應成功",content = @Content(mediaType = "application/json",schema = @Schema(title = "Resul和StudentVO組合模型",description = "返回實體,AjaxResult內data為StudentVO模型",anyOf = {Result.class, StudentVO.class}))),@ApiResponse(responseCode = "500",description = "響應失敗",content = @Content(mediaType = "application/json",schema = @Schema(title = "Resul模型",description = "返回實體,Result內 data為空",implementation = Result.class)))})@GetMapping("/{id}")public Result<StudentVO> findOneStudent(@PathVariable(value = "id") Long id) {//模擬學生數據List<String> likes = Arrays.asList("抓魚", "爬山", "寫字");StudentVO studentVO = new StudentVO(id, "張三", 22, "惠州", 93.5, likes);return new Result<StudentVO>(200, "成功", studentVO);}@Operation(summary = "查詢全部學生數據",description = "查詢學生信息,并返回響應結果信息",responses = {@ApiResponse(responseCode = "200",description = "響應成功",content = @Content(mediaType = "application/json",schema = @Schema(title = "AjaxResul和StudentVO組合模型",description = "返回實體,Result內data為StudentVO模型(并且StudentVO為集合)",anyOf = {Result.class, StudentVO.class})))})@GetMapping("/lists")public Result<List<StudentVO>> findAllStudent() {//模擬學生數據List<String> likes = Arrays.asList("抓魚", "爬山", "寫字");StudentVO student1 = new StudentVO(1L, "張三", 22, "深圳", 93.5, likes);StudentVO student2 = new StudentVO(2L, "李四", 24, "惠州", 99.5, likes);return new Result(200, "成功", Arrays.asList(student1, student2));}@Operation(summary = "學生查詢接口", description = "學生查詢接口")@GetMapping("/query")public Result<List<StudentVO>> queryStudent(QueryStudentDTO queryStudentDTO) {//模擬學生數據List<String> likes = Arrays.asList("抓魚", "爬山", "寫字");StudentVO student1 = new StudentVO(1L, "張三", 22, "廣東深圳", 93.5, likes);StudentVO student2 = new StudentVO(2L, "李四", 24, "廣東惠州", 99.5, likes);return new Result<List<StudentVO>>(200, "成功", Arrays.asList(student1, student2));}@Operation(summary = "學生添加接口", description = "學生添加接口")@PostMappingpublic Result saveStudent(@RequestBody StudentDTO studentDTO) {System.out.println("成功添加數據:" + studentDTO);return new Result(200, "成功", null);}}
參考資料
- Spring Boot 3.x 中使用 SpringDoc 2 / Swagger3(詳解)-騰訊云開發者社區-騰訊云
- SpringBoot3整合SpringDoc實現在線接口文檔 - 程序員曉凡 - 博客園
- https://swagger.io/docs/open-source-tools/swagger-ui/usage/configuration/
- https://springdoc.org/#getting-started
- https://springdoc.org/#migrating-from-springfox
- https://www.cnblogs.com/antLaddie/p/17418078.html