集成 Spring Doc 介面文檔和 knife4j-SpringBoot 2.7.2 實戰基礎

来源:https://www.cnblogs.com/youyacoder/archive/2022/08/08/16562539.html
-Advertisement-
Play Games

集成 Spring Doc 介面文檔和 knife4j 前面已經集成 MyBatis Plus、Druid 數據源,開發了 5 個介面。在測試這 5 個介面時使用了 HTTP Client 或 PostMan,無論是啥都比較麻煩:得自己寫請求地址 URL、請求參數等,於是多年前就出現了 Swagg... ...


優雅哥 SpringBoot 2.7.2 實戰基礎 - 04 -集成 Spring Doc 介面文檔和 knife4j

前面已經集成 MyBatis Plus、Druid 數據源,開發了 5 個介面。在測試這 5 個介面時使用了 HTTP Client 或 PostMan,無論是啥都比較麻煩:得自己寫請求地址 URL、請求參數等,於是多年前就出現了 Swagger 這個玩意。Swagger 可以自動生成介面文檔,還能很方便的測試各個介面。但不幸的是,MVN Repository 上面 Springfox Swagger2 的版本停止於 2020 年 7月,而寫下這篇文章是 2022 年 8 月,已經兩年過去沒有動靜了,與此同時,springdoc-openapi 悄然出現。

spring doc open api 支持 Open API 3、Swagger-ui等,可以很方便與 Spring Boot 整合,配置和使用與 Springfox Swagger2 類似。

1 集成 Spring Doc

1.1 添加依賴

springdoc-openapi 不是 Spring Framework 官方團隊開發的,而是社區項目,沒有包含在 spring-boot-dependencies 中。故需要先定義版本號:

<properties>
		....
    <springdoc-openapi-ui.version>1.6.9</springdoc-openapi-ui.version>
</properties>

添加依賴:

<dependency>
    <groupId>org.springdoc</groupId>
    <artifactId>springdoc-openapi-ui</artifactId>
    <version>${springdoc-openapi-ui.version}</version>
</dependency>

該依賴裡面使用了 swagger-ui,以HTML形式展示文檔。

1.2 編寫配置類

其實配置類寫不寫都可以,如果不寫配置類,就通過註解定義文檔信息就可以。創建類:com.yygnb.demo.config.SpringDocConfig

package com.yygnb.demo.config;

import io.swagger.v3.oas.models.ExternalDocumentation;
import io.swagger.v3.oas.models.OpenAPI;
import io.swagger.v3.oas.models.info.Info;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

@Configuration
public class SpringDocConfig {

    private String title = "Hero SpringBoot Demo";
    private String description = "Hero Demo for usage of Spring Boot";
    private String version = "v0.0.1";
    private String websiteName = "Hero Website";
    private String websiteUrl = "http://www.yygnb.com";

    @Bean
    public OpenAPI heroOpenAPI() {
        return new OpenAPI()
                .info(new Info().title(title)
                        .description(description)
                        .version(version))
                .externalDocs(new ExternalDocumentation().description(websiteName)
                        .url(websiteUrl));
    }
}

上面的配置定義了展示的文檔的信息,與界面上對應關係如下:

image-20220729104035602

在配置文件中除了可以配置文檔的信息,還可以配置文檔分組、Authorization 等,在後面的企業級實戰文章中會具體描寫,將會在網關層 spring cloud gateway 中集成所有微服務的介面。

1.3 配置yml

在 application.yml 配置 springdoc:

# 介面文檔
springdoc:
  packages-to-scan: com.yygnb.demo.controller
  swagger-ui:
    enabled: true

這兩項不配置也可以,packages-to-scan 預設為啟動類所在的路徑;springdoc.swagger-ui.enabled 預設為true,配置後可以在不同的環境中開啟或關閉。

1.4 添加註解

springdoc-openapi 與 springfox-swagger2 提供的註解有很大差別:

swagger 2 spring doc 描述
@Api @Tag 修飾 controller 類,類的說明
@ApiOperation @Operation 修飾 controller 中的介面方法,介面的說明
@ApiModel @Schema 修飾實體類,該實體的說明
@ApiModelProperty @Schema 修飾實體類的屬性,實體類中屬性的說明
@ApiImplicitParams @Parameters 介面參數集合
@ApiImplicitParam @Parameter 介面參數
@ApiParam @Parameter 介面參數

修改實體類 Computer,添加 springdoc-openapi 註解:

@Schema(title = "電腦")
@Data
@NoArgsConstructor
@AllArgsConstructor
@Builder
public class Computer implements Serializable {

    private static final long serialVersionUID = 1L;

    @TableId(value = "id", type = IdType.AUTO)
    private Long id;

    @Schema(title = "尺寸")
    private BigDecimal size;

    @Schema(title = "操作系統")
    private String operation;

    @Schema(title = "年份")
    private String year;
}

修改控制器 ComputerController,添加註解:

@Tag(name = "電腦相關介面")
@RequiredArgsConstructor
@RestController
@RequestMapping("/computer")
public class ComputerController {

    private final IComputerService computerService;

    @Operation(summary = "根據id查詢電腦")
    @GetMapping("/{id}")
    public Computer findById(
            @Parameter(name = "id", required = true, description = "電腦id") @PathVariable Long id) {
        return this.computerService.getById(id);
    }

    @Operation(summary = "分頁查詢電腦列表")
    @Parameters(value = {
            @Parameter(name = "page", description = "頁面,從1開始", example = "2"),
            @Parameter(name = "size", description = "每頁大小", example = "10")
    })
    @GetMapping("/find-page/{page}/{size}")
    public Page<Computer> findPage(@PathVariable Integer page, @PathVariable Integer size) {
        return this.computerService.page(new Page<>(page, size));
    }

    @Operation(summary = "新增電腦")
    @PostMapping()
    public Computer save(@RequestBody Computer computer) {
        computer.setId(null);
        this.computerService.save(computer);
        return computer;
    }

    @Operation(summary = "根據id修改電腦")
    @PutMapping("/{id}")
    public Computer update(
            @Parameter(name = "id", required = true, description = "電腦id") @PathVariable Long id,
            @RequestBody Computer computer) {
        computer.setId(id);
        this.computerService.updateById(computer);
        return computer;
    }

    @Operation(summary = "根據id刪除電腦")
    @DeleteMapping("/{id}")
    @Parameter(name = "id", required = true, description = "電腦id")
    public void delete(@PathVariable Long id) {
        this.computerService.removeById(id);
    }
}

1.5 運行測試

啟動服務,在瀏覽器中訪問:

http://localhost:9099/swagger-ui/index.html

image-20220729110218650

2 api-docs

在文檔標題下麵有一個小鏈接:/v3/api-docs,點擊該鏈接,會在新頁面中顯示一大坨 JSON 數據。

image-20220729111003036

看似很無聊的數據,卻有著重大意義,swagger-ui 就是通過這些數據渲染出頁面的。此外,這些JSON數據在某種程度上可以簡化前端的開發及前後端網路請求的工作量。

hero-admin-ui

優雅哥正在開發的基於 Vue 3 + TypeScript 的開源項目 hero-admin-ui,其特色就是基於 JSON Schema 的表單和列表。通過 JSON Schema 可以快速渲染出一個列表、表單,甚至是搜索頁和詳情表單頁。如果獨立使用 hero-admin-ui,需要手動編寫 JSON Schema,但如果後端介面整合了 Swagger 或 Spring Doc,上面 api-docs 返回的 JSON,就包含了 JSON Schema,二者結合可以快速實現搜索頁、表單頁等。目前 hero-admin-ui 已發佈在 npmjs 上,也已經提交到 github上,大家可以搜索關鍵字 hero-admin-ui 查看。在後面的實戰篇中,前端部分將會使用這個組件庫實現前端頁面。

image-20220729112239715

3 自定義配置

在 ”1.2 編寫配置類“ 一節,文檔信息都是寫死在代碼中的,如果多個微服務都要集成 spring doc,可以把前面寫的 SpringDocConfig 提取到公共模塊中,通過maven 依賴引用,在 application.yml 中配置不同的變數。

3.1 添加依賴

<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-configuration-processor</artifactId>
    <optional>true</optional>
</dependency>

配置該依賴的目的是在編寫 application.yml 時,自定義的屬性有代碼提示。它會生成配置元數據,無需自己手動編寫。

3.2 定義配置的實體類

創建 com.yygnb.demo.config.DocInfo,將 SpringDocConfig 中寫死的屬性都移到這個配置實體類中:

@Data
@Component
@ConfigurationProperties(prefix = "doc-info")
public class DocInfo {

    private String title = "Demo Title";
    private String description = "Demo Description";
    private String version = "v0.0.1";
    private String websiteName = "Demo Website";
    private String websiteUrl = "http://www.yygnb.com";
}

註解 @ConfigurationProperties(prefix = "doc-info") 聲明配置屬性,在 application.yml 配置時就可以使用 doc-info。

3.3 重構 SpringDocConfig

在 SpringDocConfig 中引入 DocInfo,並通過構造函數進行註入:

@RequiredArgsConstructor
@Configuration
public class SpringDocConfig {

    private final DocInfo docInfo;

    @Bean
    public OpenAPI springShopOpenAPI() {
        return new OpenAPI()
                .info(new Info().title(docInfo.getTitle())
                        .description(docInfo.getDescription())
                        .version(docInfo.getVersion()))
                .externalDocs(new ExternalDocumentation().description(docInfo.getWebsiteName())
                        .url(docInfo.getWebsiteUrl()));
    }
}

補充一個小點:註解 @RequiredArgsConstructor 是 lombok 中提供的,它等價於在類中編寫了方法:

public SpringDocConfig(DocInfo docInfo) {
    this.docInfo = docInfo;
}

構造註入時,在構造函數中寫大量的屬性,毫無意義。既然已經使用了 @Data 註解,為啥不用 @RequiredArgsConstructor 呢?

3.4 使用自定義配置

自定義配置已經完成,可以在 application.yml 中使用 DocInfo 對應的配置了:

doc-info:
  title: SpringBoot Demo演示
  description: 學習 Spring Boot 2.7.2

DocInfo 所有屬性都定義了預設值,在 application.yml 可以覆蓋預設值,如上面的 titledescription 屬性。重啟服務查看運行效果:

image-20220729152109364

4 集成 knife4j

在之前 springfox-swagger 的時代,很多同學不喜歡 swagger-ui 的界面風格,會集成 knife4j 的 ui。Spring Doc 也可以集成 knife4j。

如果要使用 knife4j ,Spring Doc 的配置中需要添加分組配置,我們這裡添加一個最簡單的分組配置。

com.yygnb.demo.config.SpringDocConfig

@RequiredArgsConstructor
@Configuration
public class SpringDocConfig {

    private final DocInfo docInfo;

    @Bean
    public OpenAPI heroOpenAPI() {
        return new OpenAPI()
                .info(new Info().title(docInfo.getTitle())
                        .description(docInfo.getDescription())
                        .version(docInfo.getVersion()))
                .externalDocs(new ExternalDocumentation().description(docInfo.getWebsiteName())
                        .url(docInfo.getWebsiteUrl()));
    }

    @Bean
    public GroupedOpenApi publicApi() {
        return GroupedOpenApi.builder()
                .group(docInfo.getTitle())
                .pathsToMatch("/**")
                .build();
    }
}

如果不添加這個 GroupedOpenApi 實例,knife4j ui就顯示不出來。

在 pom.xml 中引入 knife4j

<properties>
...
    <knife4j-springdoc-ui.version>3.0.3</knife4j-springdoc-ui.version>
</properties>

<dependencies>
...
    <dependency>
        <groupId>com.github.xiaoymin</groupId>
        <artifactId>knife4j-springdoc-ui</artifactId>
        <version>${knife4j-springdoc-ui.version}</version>
    </dependency>
</dependencies>

啟動服務,訪問:

http://localhost:9099/doc.html

顯示 knife4j 的ui:

image-20220804103201647

image
今日優雅哥(工\/youyacoder)學習結束,期待關註留言分享~~


您的分享是我們最大的動力!

-Advertisement-
Play Games
更多相關文章
  • python 爬取 博客園 接 螞蟻學pythonP5生產者消費者爬蟲數據重覆問題 先看訪問地址 訪問地址是https://www.cnblogs.com/#p2 但是實際訪問地址是https://www.cnblogs.com 說明其中存在貓膩;像這種我們給定指定頁碼,按理應該是 post 請求才 ...
  • 變數用法與特征 變數綁定 let a = "hello world" 為何不用賦值而用綁定呢(其實你也可以稱之為賦值,但是綁定的含義更清晰準確)?這裡就涉及 Rust 最核心的原則——所有權,簡單來講,任何記憶體對象都是有主人的,而且一般情況下完全屬於它的主人,綁定就是把這個對象綁定給一個變數,讓這個 ...
  • 目錄 一.簡介 二.效果演示 三.源碼下載 四.猜你喜歡 零基礎 OpenGL (ES) 學習路線推薦 : OpenGL (ES) 學習目錄 >> OpenGL ES 基礎 零基礎 OpenGL (ES) 學習路線推薦 : OpenGL (ES) 學習目錄 >> OpenGL ES 轉場 零基礎 O ...
  • 微信登錄之前還需要瞭解OAuth2知識 前期準備 註冊微信開放平臺 郵箱激活 完善開發者資料(暫不支持個體用戶) 開發者資質認證:營業執照、1-2個工作如審批、300元 網站應用:最好是已經部署到伺服器上的項目,7個工作日審批 審核通過之後會有AppID和AppSecret兩個值 AppID: 申請 ...
  • 有時候我們需要把自己寫的類或者函數給別人使用,但又不希望讓別人知道具體的實現,那麼封裝成庫就是一個很好的方法。本文描述了怎麼去把一個C++程式封裝成一個靜態庫並且如何去使用這些靜態庫。 ...
  • 精華筆記: package:聲明包 作用:避免類的命名衝突 同包中的類不能同名,但不同包中的類可以同名 類的全稱:包名.類名,包名常常有層次結構 建議:包名所有字母都小寫 import:導入類 同包中的類可以直接訪問 不同包中的類不能直接訪問,若想訪問: 先import導入類再使用類 建議 類的全稱 ...
  • Java常用類 5.其他常用類 5.1Math類 java.lang.Math提供了一系列靜態方法用於科學計算;其方法的參數和返回值類型一般為double型。如果需要更加強大的數學運算能力,計算高等數學中相關內容,可以使用apache commons下麵的Math類庫。 package li.nor ...
  • 課程導讀 俗話說:工欲善其事必先利其器。想要快速寫出好的代碼,更是離不開一個好的工具。在這個快速發展的社會,一個好的工具,能幫我們在開發過程中節省大量的開發時間。本套課程給同學們帶來Java目前最流行,最好用的集成開發工具Intellij Idea。(PS:這套課程是面向所有階段的學員的哦~) ht ...
一周排行
    -Advertisement-
    Play Games
  • 移動開發(一):使用.NET MAUI開發第一個安卓APP 對於工作多年的C#程式員來說,近來想嘗試開發一款安卓APP,考慮了很久最終選擇使用.NET MAUI這個微軟官方的框架來嘗試體驗開發安卓APP,畢竟是使用Visual Studio開發工具,使用起來也比較的順手,結合微軟官方的教程進行了安卓 ...
  • 前言 QuestPDF 是一個開源 .NET 庫,用於生成 PDF 文檔。使用了C# Fluent API方式可簡化開發、減少錯誤並提高工作效率。利用它可以輕鬆生成 PDF 報告、發票、導出文件等。 項目介紹 QuestPDF 是一個革命性的開源 .NET 庫,它徹底改變了我們生成 PDF 文檔的方 ...
  • 項目地址 項目後端地址: https://github.com/ZyPLJ/ZYTteeHole 項目前端頁面地址: ZyPLJ/TreeHoleVue (github.com) https://github.com/ZyPLJ/TreeHoleVue 目前項目測試訪問地址: http://tree ...
  • 話不多說,直接開乾 一.下載 1.官方鏈接下載: https://www.microsoft.com/zh-cn/sql-server/sql-server-downloads 2.在下載目錄中找到下麵這個小的安裝包 SQL2022-SSEI-Dev.exe,運行開始下載SQL server; 二. ...
  • 前言 隨著物聯網(IoT)技術的迅猛發展,MQTT(消息隊列遙測傳輸)協議憑藉其輕量級和高效性,已成為眾多物聯網應用的首選通信標準。 MQTTnet 作為一個高性能的 .NET 開源庫,為 .NET 平臺上的 MQTT 客戶端與伺服器開發提供了強大的支持。 本文將全面介紹 MQTTnet 的核心功能 ...
  • Serilog支持多種接收器用於日誌存儲,增強器用於添加屬性,LogContext管理動態屬性,支持多種輸出格式包括純文本、JSON及ExpressionTemplate。還提供了自定義格式化選項,適用於不同需求。 ...
  • 目錄簡介獲取 HTML 文檔解析 HTML 文檔測試參考文章 簡介 動態內容網站使用 JavaScript 腳本動態檢索和渲染數據,爬取信息時需要模擬瀏覽器行為,否則獲取到的源碼基本是空的。 本文使用的爬取步驟如下: 使用 Selenium 獲取渲染後的 HTML 文檔 使用 HtmlAgility ...
  • 1.前言 什麼是熱更新 游戲或者軟體更新時,無需重新下載客戶端進行安裝,而是在應用程式啟動的情況下,在內部進行資源或者代碼更新 Unity目前常用熱更新解決方案 HybridCLR,Xlua,ILRuntime等 Unity目前常用資源管理解決方案 AssetBundles,Addressable, ...
  • 本文章主要是在C# ASP.NET Core Web API框架實現向手機發送驗證碼簡訊功能。這裡我選擇是一個互億無線簡訊驗證碼平臺,其實像阿裡雲,騰訊雲上面也可以。 首先我們先去 互億無線 https://www.ihuyi.com/api/sms.html 去註冊一個賬號 註冊完成賬號後,它會送 ...
  • 通過以下方式可以高效,並保證數據同步的可靠性 1.API設計 使用RESTful設計,確保API端點明確,並使用適當的HTTP方法(如POST用於創建,PUT用於更新)。 設計清晰的請求和響應模型,以確保客戶端能夠理解預期格式。 2.數據驗證 在伺服器端進行嚴格的數據驗證,確保接收到的數據符合預期格 ...