集成 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
  • 概述:在C#中,++i和i++都是自增運算符,其中++i先增加值再返回,而i++先返回值再增加。應用場景根據需求選擇,首碼適合先增後用,尾碼適合先用後增。詳細示例提供清晰的代碼演示這兩者的操作時機和實際應用。 在C#中,++i 和 i++ 都是自增運算符,但它們在操作上有細微的差異,主要體現在操作的 ...
  • 上次發佈了:Taurus.MVC 性能壓力測試(ap 壓測 和 linux 下wrk 壓測):.NET Core 版本,今天計劃準備壓測一下 .NET 版本,來測試並記錄一下 Taurus.MVC 框架在 .NET 版本的性能,以便後續持續優化改進。 為了方便對比,本文章的電腦環境和測試思路,儘量和... ...
  • .NET WebAPI作為一種構建RESTful服務的強大工具,為開發者提供了便捷的方式來定義、處理HTTP請求並返迴響應。在設計API介面時,正確地接收和解析客戶端發送的數據至關重要。.NET WebAPI提供了一系列特性,如[FromRoute]、[FromQuery]和[FromBody],用 ...
  • 原因:我之所以想做這個項目,是因為在之前查找關於C#/WPF相關資料時,我發現講解圖像濾鏡的資源非常稀缺。此外,我註意到許多現有的開源庫主要基於CPU進行圖像渲染。這種方式在處理大量圖像時,會導致CPU的渲染負擔過重。因此,我將在下文中介紹如何通過GPU渲染來有效實現圖像的各種濾鏡效果。 生成的效果 ...
  • 引言 上一章我們介紹了在xUnit單元測試中用xUnit.DependencyInject來使用依賴註入,上一章我們的Sample.Repository倉儲層有一個批量註入的介面沒有做單元測試,今天用這個示例來演示一下如何用Bogus創建模擬數據 ,和 EFCore 的種子數據生成 Bogus 的優 ...
  • 一、前言 在自己的項目中,涉及到實時心率曲線的繪製,項目上的曲線繪製,一般很難找到能直接用的第三方庫,而且有些還是定製化的功能,所以還是自己繪製比較方便。很多人一聽到自己畫就害怕,感覺很難,今天就分享一個完整的實時心率數據繪製心率曲線圖的例子;之前的博客也分享給DrawingVisual繪製曲線的方 ...
  • 如果你在自定義的 Main 方法中直接使用 App 類並啟動應用程式,但發現 App.xaml 中定義的資源沒有被正確載入,那麼問題可能在於如何正確配置 App.xaml 與你的 App 類的交互。 確保 App.xaml 文件中的 x:Class 屬性正確指向你的 App 類。這樣,當你創建 Ap ...
  • 一:背景 1. 講故事 上個月有個朋友在微信上找到我,說他們的軟體在客戶那邊隔幾天就要崩潰一次,一直都沒有找到原因,讓我幫忙看下怎麼回事,確實工控類的軟體環境複雜難搞,朋友手上有一個崩潰的dump,剛好丟給我來分析一下。 二:WinDbg分析 1. 程式為什麼會崩潰 windbg 有一個厲害之處在於 ...
  • 前言 .NET生態中有許多依賴註入容器。在大多數情況下,微軟提供的內置容器在易用性和性能方面都非常優秀。外加ASP.NET Core預設使用內置容器,使用很方便。 但是筆者在使用中一直有一個頭疼的問題:服務工廠無法提供請求的服務類型相關的信息。這在一般情況下並沒有影響,但是內置容器支持註冊開放泛型服 ...
  • 一、前言 在項目開發過程中,DataGrid是經常使用到的一個數據展示控制項,而通常表格的最後一列是作為操作列存在,比如會有編輯、刪除等功能按鈕。但WPF的原始DataGrid中,預設只支持固定左側列,這跟大家習慣性操作列放最後不符,今天就來介紹一種簡單的方式實現固定右側列。(這裡的實現方式參考的大佬 ...