SprongBoot3整合Knife4j

程序员晓凡發表於2024-07-01

大家好,我是曉凡。

寫在前面

在上一篇文章,我們詳細介紹了SpringBoot3 怎麼整合SpringDoc實現線上介面文件。但是,有不少小夥伴

都覺得介面介面太醜了。有沒有什麼更美觀一點的UI介面呢?

當然是有的了,畢竟這是一個看臉的時代,Knife4j 這不來了麼。

一、介面比較

這兒我們將上一篇文章使用swagger UIKnife4j UI做一個比較,哪個好看就不用我多說了吧。

swaggerUI介面

swaggerUI介面

Knife4j UI介面

Knife4j UI介面

二、Knife4j 是什麼?

Knife4j 是一個為 Java 專案生成和管理 API 文件的工具。實際上,它是 Swagger UI的一個增強工具集,

旨在讓 Swagger 生成的 API線上文件更加優雅、美觀、強大。

① 官方地址

http://knife4j.net/

②文件地址

https://doc.xiaominfo.com/docs/quick-start

三、為什麼要使用Knife4j

使用Knife4j主要有以下優點,就問哪個不吸引我們呢?

  • 美觀的UI:相比於原生 Swagger UIKnife4j 提供了更加人性化和美觀的介面設計
  • 豐富的文件互動功能:支援線上除錯、請求引數動態輸入、介面排序等
  • 個性化配置:可自定義 API 文件的介面風格,實現文件介面的個性化展示

四、Knife4j版本介紹

目前,我們使用的SpringBoot 版本主要是2和3,不同的boot版本需要適配不同版本的Knife4j.

透過這一小節,我們將在專案中選擇合適的Knife4j版本

4.1 Knife4j的前世今生

在更名為Knife4j之前,原來的名稱是叫swagger-bootstrap-ui,這是兩種不一樣風格的Ui,區別如下

名稱 開發語言&框架 狀態 最後版本 風格
Knife4j JavaJavaScriptVue 持續更新中... 黑色
swagger-bootstrap-ui JavaJavaScriptjQuery 停更 1.9.6 藍色

Knife4j從開源至今,目前主要經歷版本的變化,分別如下:

版本 說明
1.0~1.9.6 名稱是叫swagger-bootstrap-ui,藍色風格Ui
1.9.6 藍色皮膚風格,開始更名,增加更多後端模組
2.0~2.0.5 Ui基於Vue2.0+AntdV重寫,黑色風格,底層依賴的springfox2.9.2,僅提供Swagger2規範的適配
2.0.6~2.0.9 底層依賴springfox2.10.5,僅提供Swagger2規範的適配
3.0~3.0.3 底層依賴springfox3.0.3,是過度版本,不建議使用
4.0~ Knife4j對於支援不同協議,依賴的是第三方元件,需要引入不同依賴
OpenAPI2(Swagger2)規範,依賴Springfox專案,專案處於停更狀態,不建議使用
OpenAPI3(Swagger3)規範,依賴Springdoc專案,更新頻率快,建議使用該版本

4.2 Spring Boot版本相容性

Spring Boot版本 Knife4j Swagger2規範 Knife4j OpenAPI3規範
1.5.x~2.0.0 <Knife4j 2.0.0 >=Knife4j 4.0.0
2.0~2.2 Knife4j 2.0.0 ~ 2.0.6 >=Knife4j 4.0.0
2.2.x~2.4.0 Knife4j 2.0.6 ~ 2.0.9 >=Knife4j 4.0.0
2.4.0~2.7.x >=Knife4j 4.0.0 >=Knife4j 4.0.0
>= 3.0 >=Knife4j 4.0.0 >=Knife4j 4.0.0

如果你不考慮使用Knife4j提供的服務端增強功能,引入Knife4j的純Ui版本沒有任何限制。只需要考慮不同的規範即可

五、快速開始

透過上面的介紹,相信你已經對Knife4j 有了整體的認識,接下來我們就使用SpringBoot3快速整合Knife4j

我們這選用的環境如下

  • jdk17
  • SpringBoot3.3.1
  • knife4j 4.4.0
  • OpenAPI3協議規範

5.1 新建一個web專案

建一個名為knife4j-spring-boot3-demo 的web專案,專案結構如下

專案結構

5.2 新增Knife4j 依賴

⚠️溫馨提示

我們這裡使用的是SpringBoot3

  • Spring Boot 3 只支援OpenAPI3規範
  • Knife4j提供的starter已經引用springdoc-openapi的jar,需注意避免jar包衝突
  • JDK版本必須 >= 17
<dependency>
    <groupId>com.github.xiaoymin</groupId>
    <artifactId>knife4j-openapi3-jakarta-spring-boot-starter</artifactId>
    <version>4.4.0</version>
</dependency>

5.3 新建hello介面

新建controller包,新增HelloController類,程式碼如下

@RestController
public class HelloController {
    @GetMapping("/hello")
    public String hello(){
        return "hello";
    }
}

5.4 訪問Knife4j線上文件

瀏覽器輸入:http://localhost:8080/doc.html 訪問線上介面文件

線上介面文件

六、Knife4j 常用配置

⚠️溫馨提示:

增強功能需要透過配置application.yml配置檔案開啟增強,後面不再贅述,預設開啟

knife4j:
enable: true

6.1 專案配置

application.yml中可以自定義api-docsswagger-ui的訪問路徑。當然了,如果沒配置,預設就是下面路徑

注:這兒還是相容swagger ui頁面展示

springdoc:
  swagger-ui:
    path: /swagger-ui.html
    tags-sorter: alpha
    operations-sorter: alpha
  api-docs:
    path: /v3/api-docs
  group-configs:
    - group: 'default'
      paths-to-match: '/**'
      packages-to-scan: com.xiezhr.knife4jspringboot3demo.controller

瀏覽器輸入:http://localhost:8080/swagger-ui/index.html 可按照原來ui來顯示

swagger-ui

6.2 配置介面文件基本資訊

① 配置介面基本資訊

新建一個config包--->並在包下建立一個Knife4jConfig配置類

Knife4jConfig配置類

② 配置介面文件基礎資訊

這兒我們可以配置介面文件標題、介面文件版本資訊、介面文件描述資訊、介面文件聯絡人資訊,介面文件license許可證資訊

我們只需在配置類中新增如下程式碼即可

@Configuration
public class Knife4jConfig {

    @Bean
    public OpenAPI openAPI() {
        return new OpenAPI()
                // 配置介面文件基本資訊
                .info(this.getApiInfo())
                ;
    }

    private Info getApiInfo() {
        return new Info()
                // 配置文件標題
                .title("SpringBoot3整合Knife4j")
                // 配置文件描述
                .description("SpringBoot3整合Knife4j示例文件")
                // 配置作者資訊
                .contact(new Contact().name("程式設計師曉凡").url("https://www.xiezhrspace.cn").email("1666397814@163.com"))
                // 配置License許可證資訊
                .license(new License().name("Apache 2.0").url("https://www.xiezhrspace.cn"))
                // 概述資訊
                .summary("SpringBoot3整合Knife4j示例文件aaa")
                .termsOfService("https://www.xiezhrspace.cn")
                // 配置版本號
                .version("2.0");
    }
}

瀏覽器輸入:http://localhost:8080/doc.html 訪問顯示如下

介面基本資訊

6.3 i18n國際化

Knife4j提供了i18n的支援,支援的語言主要包含2種:中文(zh-CN)、英文(en-US)。預設是中文

①透過下拉框選擇

透過訪問doc.html開啟文件介面,可以在文件的右上角看到語言的選擇,如下圖:

語言選擇

② 透過文件地址也可以選擇

  • 中文:http://host:port/doc.html#/home/zh-CN
  • 英文:http://host:port/doc.html#/home/en-US

另外,如果你是使用了knife4j提供的增強功能,你也可以這樣訪問

  • 中文:http://host:port/doc.html#/plus/zh-CN
  • 英文:http://host:port/doc.html#/plus/en-US

③ 透過application.yml配置檔案設定

knife4j:
  enable: true
  setting:
    language: zh_cn

6.4 介面新增作者

介面程式碼如下,我們給hello介面新增作者“張三”

@ApiOperationSupport(author = "張三")
@GetMapping("/hello")
public String hello(){
    return "hello";
}

介面作者

6.5 自定義文件

有時候在OpenAPI不足以滿足介面說明的情況下,我們可以透過.md格式檔案擴充系統文件說明

①新增自定義文件

我們可以在當前專案中新增多個資料夾,資料夾中存放.md格式的markdown檔案,每個.md文件代表一份自定義文件說明。

這裡,我們在預設組default 下面新增介面簽名認證文件說明.md自定義文件說明.md 兩個文件,結構如下

文件結構

每個.md檔案中,Knife4j允許一級(h1)、二級(h2)、三級(h3)標題作為最終的文件標題

比如,上面新增的自定義文件說明.md內容如下

# 自定義文件說明

## 效果說明

`knife4j`為了滿足文件的個性化配置,新增了自定義文件功能

開發者可自定義`md`檔案擴充套件補充整個系統的文件說明

開發者可以在當前專案中新增一個資料夾,資料夾中存放`.md`格式的markdown檔案,每個`.md`文件代表一份自定義文件說明

**注意**:自定義文件說明必須以`.md`結尾的檔案,其他格式檔案會被忽略

② 配置自定義文件顯示

文件新增好之後,我們在application.yml 新增如下配置資訊

knife4j:
  documents:
    - group: default
      name: 其他文件
      # 某一個資料夾下所有的.md檔案
      locations: classpath:markdown/*

配置說明:

  • group: 分組的名稱,這兒我們還沒有配置分組,所以預設的是default
  • name: 介面呈現時選單顯示
  • locations: markdown文件路徑

③ 前端介面呈現效果

上述資訊配置好之後,在瀏覽器訪問doc.html 如下

自定義文件顯示

6.6 訪問許可權控制

為了保證生產環境下介面服務安全,我們可以提供一個登陸介面的功能,只有輸入使用者名稱和密碼才能訪問

① 在application.yml 中新增如下配置

knife4j:
  enable: true
  basic:
    enable: true
    username: xiezhr
    password: 123456

②需要輸入正確的使用者名稱和密碼才能訪問

許可權控制

6.7 介面排序

使用Knife4j提供的增強註解@ApiOperationSupport中的order欄位可進行介面排序

HelloController 中有hellogetToken 兩個介面,我們要實現getToken介面顯示在前面,程式碼如下

① 修改application.yml

springdoc:
  swagger-ui:
    operations-sorter: order

② 調整@ApiOperationSupport中的order

@RestController
public class HelloController {
    @ApiOperationSupport(author = "張三",order = 2)
    @GetMapping("/hello")
    public String hello(){
        return "hello";
    }

    @ApiOperationSupport(author = "李四" ,order = 1)
    @GetMapping("/access-appid")
    public String getToken(){

        return "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG4gRG9lIiwiaWF0IjoxNTE2MjM5MDIyfQ.SflKxwRJSMeKKF2QT4fwpMeJf36POk6yJV_adQssw5c";
    }
}

③ 介面顯示順序如下

介面排序

6.8 介面分組

為了演示API分組,我們在controller包下面再建立admin包和common包,包下分別新增AdminControllerCommonController介面類,結構及程式碼如下

image-20240630152601955

AdminController

@RequestMapping("admin")
@RestController
public class AdminController {

    @GetMapping("/access-appid")
    public String getToken(){

        return "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG4gRG9lIiwiaWF0IjoxNTE2MjM5MDIyfQ.SflKxwRJSMeKKF2QT4fwpMeJf36POk6yJV_adQssw5c";
    }
}

CommonController

@RequestMapping("common")
@RestController
public class CommonController {

    @GetMapping("/hello")
    public String hello(){
        return "hello";
    }

    @GetMapping("/hi")
    public String Hi(){
        return "Hi 程式設計師曉凡";
    }
}

在預設情況(沒有分組)的情況下,所有包下介面都顯示在一一個預設組下面,如/common/* 和/admin/* 訪問路徑下的介面都顯示在一起,如下圖所示

default分組

這時,如果/common/* 下的介面比較多,/admin/* 下的介面也比較多,介面上顯示就很混亂

解決辦法就是新增分組資訊,這裡有兩種配置方法

① 透過application.yml配置 admin分組和common 兩個分組

springdoc:
  group-configs:
    - group: 'admin'
      paths-to-match: '/admin/**'
      packages-to-scan: com.xiezhr.knife4jspringboot3demo.controller
    - group: 'common'
      paths-to-match: '/common/**'
      packages-to-scan: com.xiezhr.knife4jspringboot3demo.controller

② 透過配置類Knife4jConfig新增兩個分組

@Configuration
public class SpringDocConfig {
  // 此處省去其他配置資訊......
    
    @Bean("common")
    public GroupedOpenApi webGroupApi() {
        return GroupedOpenApi.builder().group("common")
                .pathsToMatch("/common/**")
                .build();
    }

    @Bean("admin")
    public GroupedOpenApi adminGroupApi() {
        return GroupedOpenApi.builder().group("admin")
                .pathsToMatch("/admin/**")
                .build();
    }

}

以上兩種配置時等效的,再訪問:http://localhost:8080/doc.html 顯示如下

最終分組顯示

6.9 動態請求引數

在某些特定的情況下如果後端定義的是一種Map結構,或者是引數並沒有定義宣告,而希望也能達到一種動態新增引數進行除錯的結果,這種體驗有點類似於postman

① 開啟動態引數配置

knife4j:
  enable: true
  setting:
  # 開啟動態請求引數,true-開啟,false-關閉
    enable-dynamic-parameter: true

配置完後,開啟動態請求這個會勾上

動態請求

② 新增動態引數除錯

新增動態引數除錯

動態引數

6.10 過濾請求引數

通常我們在開發介面時,比如一個新增介面和一個修改介面,修改介面需要傳遞主鍵id、而新增介面則不需要傳遞此屬性,但大部分情況,我們只寫一個Model類,此時在新增介面時顯示主鍵id會顯得很多餘.

使用自定義增強註解ApiOperationSupport中的ignoreParameters屬性,可以強制忽略要顯示的引數.

忽略的規則如下:

  • 例如新增介面時,某實體類不需要顯示Id,即可使用該屬性對引數進行忽略.ignoreParameters={"id"}
  • 如果存在多個層次的引數過濾,則使用名稱.屬性的方式,例如 ignoreParameters={"uptModel.id","uptModel.uptPo.id"},其中uptModel是實體物件引數名稱,id為其屬性,uptPo為實體類,作為uptModel類的屬性名稱
  • 如果引數層級只是一級的情況下,並且引數是實體類的情況下,不需要設定引數名稱,直接給定屬性值名稱即可
  • 如果實體類屬性中是透過List這種陣列的方式,那麼過濾規則會有所不同,在屬性後面需要追加一個下標[0]ignoreParameters={"uptModel.uptPo[0].id"}

在介面過濾時,主要有兩種情況

6.10.1 表單引數

我們在使用實體類直接作為引數時,在我們的ui介面中是不會顯示引數名稱的,此時可以直接使用實體的屬性名稱進行引數忽略,例如如下程式碼:

表單型別的請求是不需要新增引數名的

@ApiOperation(value = "新增Model介面1")
@ApiOperationSupport(ignoreParameters = {"id","orderDate.id"})
@PostMapping("/insertMode1l")
public Rest<UptModel> insertModel1(UptModel uptModel){
    Rest<UptModel> r =new Rest<>();
    r.setData(uptModel);
    return r;
}

實體類UptModel.java檔案程式碼

public class UptModel {

    @ApiModelProperty(value = "主鍵id")
    private String id;

    @ApiModelProperty(value = "姓名")
    private String name;

    @ApiModelProperty(value = "郵箱")
    private String email;

    @ApiModelProperty(value = "訂單資訊")
    private OrderDate orderDate;
}

此時,最終過過濾掉UptModel的屬性id和屬性orderDate類中的id屬性,不在介面顯示.

img

6.10.2 JSON引數

如果請求引數是使用JSON的方式

程式碼如下:

@ApiOperation(value = "新增Model介面")
@ApiOperationSupport(ignoreParameters = {"uptModel.id","uptModel.name","uptModel.orderDate.id"})
@PostMapping("/insertModel")
public Rest<UptModel> insertModel(@RequestBody UptModel uptModel){
    Rest<UptModel> r =new Rest<>();
    r.setData(uptModel);
    return r;
}

此時如果要過濾id的話,需要指定帶上引數名稱uptModel

最終忽略的值為ignoreParameters = {"uptModel.id","uptModel.name","uptModel.orderDate.id"}

img

6.11 包含請求引數

時候需要忽略的引數太多時,我們需要寫很多的忽略引數屬性,此時,一個與忽略引數對立取反的特性就顯得很有幫助了

使用自定義增強註解ApiOperationSupport中的includeParameters屬性,可以強制包含要顯示的引數.去除多餘的引數

6.12 自定義Host

不同的網路環境,可以透過配置該屬性,方便的進行除錯

透過配置application.yml

knife4j:
  enable: true
  setting:
    # 是否啟用Host
    enable-host: true
    # 啟用Host後地址,例如:http://192.168.0.111:8080
    enable-host-text: "http://192.168.0.111:8080"

6.13 全域性引數

Knife4j 提供全域性引數設定功能,例如:我們可以設定全域性token引數

全域性引數功能主要提供兩種引數型別:

  • query(表單)
  • header(請求頭)

設定方法如下

全域性引數設定

6.14 自定義主頁內容

可以提供一個Markdown檔案來自定義顯示Home主頁的顯示內容,透過配置yml來進行開啟,配置檔案如下

knife4j:
  enable: true
  setting:
    enable-home-custom: true
    home-custom-path: classpath:markdown/home.md
  • enable-home-custom:該屬性為Boolean值,預設false,如果開發者要自定義主頁內容,該選項設定為true
  • home-custom-path:提供一個主頁的Markdown檔案位置

我們markdown目錄下新增home.md 文件,並新增內容之後,最終介面顯示如下

home.md

最終顯示效果

6.15 自定義Footer

Knife4j 支援自定義介面底部Footer內容,可以更改為公司或者產品介紹等資訊

未自定義前

未定義前

透過設定application.yml

knife4j:
  enable: true
  setting:
    enable-footer: true
    enable-footer-custom: true
    footer-custom-content: Apache License 2.0 | Copyright  2019-[程式設計師曉凡](https://www.xiezhrspace.cn)

image-20240630174827521

七、其他功能

7.1 匯出離線文件

使用swagger的時候,匯出一份精細的文件,需要很繁瑣的步驟,整合了knife4j之後,匯出文件變得很簡單

而且還可以匯出不同格式的文件

離線文件

7.2 匯出postman

我們還可以將介面資訊複製然後匯出到postman工具進行除錯

具體操作如下

匯出postman

7.3 生成前端呼叫程式碼

生成前端呼叫程式碼

八、小結

SpringBoot3 整合knife4j其實非常簡單,介面相對於swagger UI 確實美觀了不少。文章只列舉了常用功能,如果小夥伴有特殊的需求,可以瀏覽官方文件,官方文件還是非常詳細的。

作者也給出了各種場景的實戰demo: https://gitee.com/xiaoym/swagger-bootstrap-ui-demo

SpringBoot各種版本的整合都有案例

各種場景整合

本期內容到這兒就結束了 ★,°:.☆( ̄▽ ̄)/$:.°★ 。 希望對您有所幫助

我們下期再見 (●'◡'●) ヾ(•ω•`)o

相關文章