Springboot中整合knife4j介面文檔

在項目開發過程中,web項目的前後端分離開發,APP開發,需要由前端後端工程師共同定義介面,編寫介面文檔,之後大家都根據這個介面文檔進行開發。

什麼是knife4j

簡單說knife4j就swagger的升級版API文檔的一個框架,但是用起來比swagger方便多了,UI更加豐富。

介面欣賞

主頁

介面文檔

調試介面

參數實體

整合 knife4j

引入 maven 依賴

<dependency>
    <groupId>com.github.xiaoymin</groupId>
    <artifactId>knife4j-spring-boot-starter</artifactId>
    <!--在引用時請在maven中央倉庫搜索3.X最新版本號-->
    <version>3.0.3</version>
</dependency>

knife4j 配置文件

創建 Knife4jConfig 文件

package com.didiplus.common.config;

import com.github.xiaoymin.knife4j.spring.annotations.EnableKnife4j;
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.spi.DocumentationType;
import springfox.documentation.spring.web.plugins.Docket;

/**
 * Author: didiplus
 * Email: [email protected]
 * CreateTime: 2022/4/25
 * Desc: knife4j 配置
 */
@Configuration
@EnableKnife4j
public class Knife4jConfig {

    @Bean
    public Docket createRestApi() {
        return new Docket(DocumentationType.SWAGGER_2)
                .apiInfo(apiInfo())
                .select()
                .apis(RequestHandlerSelectors.basePackage("com.didiplus"))
                .paths(PathSelectors.any())
                .build();
    }

    private ApiInfo apiInfo() {
        return new ApiInfoBuilder()
                .title("SpringBoot項目 後台服務API介面文檔")
                .description("使用 knife4j 搭建的後台服務API介面文檔")
                .termsOfServiceUrl("//localhost:8080/")
                .contact("didiplus")
                .version("1.0.0")
                .build();
    }
}

配置API介面

package com.didiplus.modules.sys.controller;

import com.didiplus.modules.sys.domain.SysDictType;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

/**
* Author: didiplus
* Email: [email protected]
* CreateTime: 2022/4/25
* Desc: 數據字典控制器
*/
@RestController
@Api(tags = "數據字典")
@RequestMapping("/api/sys/dictType")
public class SysDictTypeController {
    
    @ApiOperation("添加")
    @PostMapping("/add")
    public SysDictType add() {
        SysDictType dictType = new SysDictType();
        dictType.setId("1");
        dictType.setTypeName("用戶狀態");
        dictType.setTypeCode("user_type");
        dictType.setDescription("用戶狀態");
        dictType.setEnable("true");
        return  dictType;
    }
    
}

通過 @Api註解標註需要生成介面文檔,通過 @ApiOperation註解標註介面名。 同時我們給 SysDictType也加上對應的註解

package com.didiplus.modules.sys.domain;

import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;

import javax.validation.constraints.NotEmpty;

/**
 * Author: didiplus
 * Email: [email protected]
 * CreateTime: 2022/4/25
 * Desc: 字典類型領域模型
 */

@Data
@ApiModel(value = "字典類型")
public class SysDictType {

    @ApiModelProperty("ID")
    private String id;

    @NotEmpty(message = "字典編碼不能為空")
    @ApiModelProperty(name = "字典名稱",example = "用戶ID")
    private String typeName;

    @NotEmpty(message = "字典編碼不能為空")
    @ApiModelProperty(value = "字典編碼")
    private String typeCode;

    @ApiModelProperty(value = "字典描述")
    private String description;

    @NotEmpty(message = "字典狀態不能為空")
    @ApiModelProperty(value = "字典狀態")
    private String enable;
}

通過 @ApiModel標註這是一個參數實體,通過 @ApiModelProperty標註欄位說明。
訪問 //localhost:8080/doc.html體驗一下,出現訪問資源異常

出現這個問題的原因是因為我們加上了 ResponseBodyAdvice統一處理返回值/響應體,導致給Swagger的返回值也包裝了一層,UI頁面無法解析。可以通過 //localhost:8080/v2/api-docs?group=SwaggerDemo觀察Swagger返回的json數據。

既然知道了問題原因那就很好解決了,我們只需要在ResponseBodyAdvice處理類中只轉換我們自己項目的介面即可。

@RestControllerAdvice(basePackages = "com.didiplus.modules")
public class ResponseAdvice  implements ResponseBodyAdvice<Object> {
....省略....
}

詳細的可以參考SpringBoot 如何統一後端返回格式。通過添加basePackage屬性限定統一返回值的範圍,這樣就不影Swagger了 ,重啟伺服器再次訪問swagger介面地址,就可以看到介面文檔頁面了。

knife4j 常用特性

knife4j 在 swagger 的基礎上做了許多增強,這裡介紹幾個最常用的。使用增強特性需在application.yml 中開啟 。

knife4j:
  production: false
  enable: true

全局參數

前後端分離開發中一般使用 token 作為請求參數進行身份與許可權鑒定,有放在 query(表單)和 header(請求頭)的,knife4j 對這兩種都進行了支援,只需在側邊欄『文檔管理 -> 全局參數設置』中設置。

離線文檔

有時我們需要一份離線文檔可以隨時隨地進行查看,knife4j 支援導出四種格式( md、html、doc 、json)的離線文檔,在側邊欄『文檔管理 -> 離線文檔』中導出。