首頁 > 軟體

Knife4j 3.0.3 整合SpringBoot 2.6.4的詳細過程

2022-09-14 22:12:25

關於 swagger 本文不再贅述,網上文章很多。本文要講的是Knife4j3.0.3 整合SpringBoot 2.6.4,因為 knife4j 3.x版本(目前只有這一個版本)和2.x版本還是有一些區別的,如果設定註解方面使用不當,很容易導致檔案頁面打不開。同時,SpringBoot 2.6.4的版本也是相對較高的版本,在SpringBoot 2.4以上的版本和之前的版本還是不一樣的,這個也容易導致一些問題。本文就這兩個版本的整合做一個實戰介紹。

一、引入依賴

<!-- Spring Boot 專案starter,快速使用knife4j增強檔案 -->
<dependency>
    <groupId>com.github.xiaoymin</groupId>
	<artifactId>knife4j-spring-boot-starter</artifactId>
	<version>3.0.3</version>
</dependency>

使用Knife4j3.0.3只需要引入這一個依賴即可,其他的swagger依賴不需要了。

這是Knife4j3.0.3版本的依賴所包含的依賴,可見,swagger的依賴已經有了。

二、程式碼設定

直接上程式碼

package com.dake.common.config;
 
import com.github.xiaoymin.knife4j.spring.annotations.EnableKnife4j;
import org.jetbrains.annotations.NotNull;
import org.springframework.beans.BeansException;
import org.springframework.beans.factory.config.BeanPostProcessor;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Import;
import org.springframework.util.ReflectionUtils;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.servlet.mvc.method.RequestMappingInfoHandlerMapping;
import springfox.bean.validators.configuration.BeanValidatorPluginsConfiguration;
import springfox.documentation.builders.ApiInfoBuilder;
import springfox.documentation.builders.PathSelectors;
import springfox.documentation.builders.RequestHandlerSelectors;
import springfox.documentation.service.ApiInfo;
import springfox.documentation.service.Contact;
import springfox.documentation.spi.DocumentationType;
import springfox.documentation.spring.web.plugins.Docket;
import springfox.documentation.spring.web.plugins.WebFluxRequestHandlerProvider;
import springfox.documentation.spring.web.plugins.WebMvcRequestHandlerProvider;
import springfox.documentation.swagger2.annotations.EnableSwagger2;
 
import java.lang.reflect.Field;
import java.util.List;
import java.util.stream.Collectors;
 
/**
 * Knife4j 3.X 設定類.
 * 存取地址:
 * <p>
 *     Knife4j 存取首頁:<a href="http://localhost:8090/doc.html#/home">...</a>
 * </p>
 *
 * @author fangqi
 * @date 2022-6-27 23:43:39
 */
@EnableKnife4j
@Configuration
@EnableSwagger2
@Import(BeanValidatorPluginsConfiguration.class)
// 在 Swagger 3.X 以下版本報錯時可以加此註解解決,但是在3.X版本以上的,加此註解會導致頁面無法開啟
//@EnableWebMvc
public class SwaggerConfig {
 
    private static final String SWAGGER_TITLE = "XXX專案 API 介面檔案";
    private static final String VERSION = "3.0.3";
 
    @Bean
    public Docket createRestApi() {
        return new Docket(DocumentationType.OAS_30)
                .enable(true)
                // .useDefaultResponseMessages(false)
                .apiInfo(apiInfo())
                .groupName("3.X 版本")
                .select()
                // 方式一: 設定掃描 所有想在swagger介面的統一管理介面,都必須在此包下
//                .apis(RequestHandlerSelectors.basePackage("com.dake.controller"))
                .apis(RequestHandlerSelectors.withClassAnnotation(RestController.class))
                // 方式二: 只有當方法上有  @ApiOperation 註解時才能生成對應的介面檔案
                // .apis(RequestHandlerSelectors.withMethodAnnotation(ApiOperation.class))
                .paths(PathSelectors.any())
                .build();
    }
 
    private ApiInfo apiInfo() {
        return new ApiInfoBuilder()
                .title(SwaggerConfig.SWAGGER_TITLE)
                .description("# XXX專案API介面檔案簡介")
                .termsOfServiceUrl("http://127.0.0.1/#/login")
                .contact(new Contact("fangqi", "", "fang_qi170@126.com"))
                .version(SwaggerConfig.VERSION)
                .build();
    }
 
    @Bean
    public static BeanPostProcessor springfoxHandlerProviderBeanPostProcessor() {
        return new BeanPostProcessor() {
            @Override
            public Object postProcessAfterInitialization(@NotNull Object bean, @NotNull String beanName) throws BeansException {
                if (bean instanceof WebMvcRequestHandlerProvider || bean instanceof WebFluxRequestHandlerProvider) {
                    customizeSpringfoxHandlerMappings(getHandlerMappings(bean));
                }
                return bean;
            }
 
            private <T extends RequestMappingInfoHandlerMapping> void customizeSpringfoxHandlerMappings(List<T> mappings) {
                List<T> copy = mappings.stream()
                        .filter(mapping -> mapping.getPatternParser() == null)
                        .collect(Collectors.toList());
                mappings.clear();
                mappings.addAll(copy);
            }
 
            @SuppressWarnings("unchecked")
            private List<RequestMappingInfoHandlerMapping> getHandlerMappings(Object bean) {
                try {
                    Field field = ReflectionUtils.findField(bean.getClass(),             "handlerMappings");
                    assert field != null;
                    field.setAccessible(true);
                    return (List<RequestMappingInfoHandlerMapping>) field.get(bean);
                } catch (IllegalArgumentException | IllegalAccessException e) {
                    throw new IllegalStateException(e);
                }
            }
        };
    }
 
}

三、組態檔

在application.yml檔案中,新增如下設定:

springfox:
  documentation:
    swagger:
      v2:
        path: /api-docs
        use-model-v3: true
 
knife4j:
  # 開啟增強
  enable: true
  # 開啟登入認證
  basic:
    enable: true
    username: admin
    password: 123456

解釋:

上面第一個設定是knife4j的設定,下面的設定是開啟增強,開啟頁面時需要 輸入賬號密碼,我們這裡賬號 是admin,密碼是123456.

四、頁面功能

瀏覽器輸入:

http://localhost:8090/doc.html#/

輸入使用者名稱和密碼即可看到我們所有的controller和加了註解的實體類。

左側一共有四個被我們用紅框框柱的頁籤。這個顯示頁面比原先的swagger的頁面風格更加美觀,也更加適合國人的使用習慣。

下面我們就這四個選單一一講解。

1.主頁

目前我們 看到的就是主頁的資訊,也就是我們這個介面檔案的簡單介紹。

2.Swagger Modules

這部分就是我們在專案中定義的實體類,我們點選開啟檢視一下。

我們看到這個實際上是層次分明的,不同的實體類型別顯示不同的 顏色,非常美觀,比起原來的swagger好看多了。

我們點開第一個看看實體類的情況。

我們看到,有欄位的英文名、中文名和資料型別,非常的清晰明瞭。

要知道,這個不是我們手寫的。是開啟頁面直接生成的,哪怕裡面的欄位變化了,只要我們重啟專案、重新整理頁面,這個介面檔案會同步進行變更,使用起來非常方便。以後再和其他同事對介面檔案的時候就非常方便了,給他一個地址加上使用者名稱密碼,讓他自己玩去,不懂了再來問。前端的小姐姐小哥哥用起來也是賊爽的。

上面的這個實體類我們還可以給他起箇中文名,那樣就更好了,當然你習慣英文名也很好。

上面設定我們設定過了,程式碼中怎麼使用呢?

五、如何使用

1.在controller上加兩個註解:

@Api(tags = "XX管理")
@ApiSupport(author = "fangqi", order = 1)

上面一共2個註解,第一個是用來說明這個controller的作用,第二個是用來說明是誰開發的,其他就是為了讓別人知道這是誰開發的檔案,到時候方便找到你。後面的那個order指的是這個controller在左邊側邊欄的展示順序。你想啊,這麼多controller,你定義一個,我定義一個,專案稍微多一些程式碼,找起來也沒有那麼方便。如果我們給他定義一個順序,豈不是美哉?order越小,越靠前。有人說了,大家都定義成1,豈不是亂了?這個當然是的,不過不會報錯,都是1,等於都沒用了而已。這個順序呢,其實由專案leader定義會更好一些。最重要的放上面,其他的按照順序排就是了。

到這裡有人說了,原來的介面是你fangqi開發的,現在呢,我要在這個上面加一個功能,也就是加一個請求的方法,到時候別人還是找你,這不合適吧!你說的沒錯,關於這一點我們可以用另外一個註解來單獨設定你增加的那個方法的作者。

比如現在有一個queryNameById的方法是fangdake新加的,那我們只需要在這個請求方法上加這個註解就行了。到時候,其他介面還是找fangqi,而你這個方法會找fangdake。

2.方法上加註解

@ApiOperationSupport(author = "fangdake")

我們上面講了,可以給類上加註解,給一箇中文的提示,告訴使用者這個controller是幹什麼的,但是方法上呢?當然了,方法上我們一樣可以給一箇中文的說明:

@ApiOperation(value = "查詢初始化資料", 
notes = "新增和修改頁面的初始化下拉選單資料", 
tags = "延伸操作")

其中,value標籤是指的方法的基本功能;notes就是一個描述性的文字,詳細的說明;tags呢,其實用處不大,在開啟介面檔案的時候它會把你這個方法再展示一份放到你給tags起的名字的這個標籤下。你開啟延伸操作的時候就能看到你加過tags標籤的方法了。其實有點類似於分組一樣,從你原先的controller中又給出了一個分組。個人感覺呢,一般是用來給測試或者領導看的。領導覺得有一二三四五,這五個功能比較重要,他可能偶爾要看看,或者這幾個方法比較重要——其實就是太難了,測試要多次測試,而且問題很多,今天測試玩明天測試。這時你就可以把不同類的不同的幾個方法抽出來放一個單獨的分組,這樣比一個選單一個選單的去找方便多了,尤其是有一些方法上面用的不是GetMapping這樣的註解,而是RequestMapping,到時候,每個方法都會在這個選單下生成很多個測試介面,也就是重複的,你會很難受。

上圖其實就是2個方法,但是我們開啟這個選單的時候會顯示這麼多。因為介面中沒有指定具體的請求方式,都是RequestMapping,所以這個介面檔案的測試功能就把所有的測試方法全部給展現出來了,不管是get、post還是delete等請求。

我們開啟一個具體的介面。

可以看到請求引數和返回引數清晰明瞭。之所以會這樣,是因為我們的請求引數和返回引數都是物件,而且我們在具體的物件上加了註解,所以才會如此。那如何操作呢,我們來看看。

首先是請求引數:

@Data
@ApiModel(description = "查詢xxx列表DTO")
public class QueryBiListDTO {
 
    @NotBlank(message = "頁碼不能為空")
    @ApiModelProperty(value = "頁碼", required = true)
    private Integer pageNo;
 
    @NotBlank(message = "每頁條數不能為空")
    @ApiModelProperty(value = "每頁條數", required = true)
    private Integer pageCount;
 
    @ApiModelProperty(value = "xxid")
    private String id;
}

返回引數同請求引數,是一樣的。

我們看到上面的那個圖片,有一個偵錯。我們點選偵錯。

我們啟動專案,上面輸入我們需要的引數,直接可以偵錯了,非常方便。不用像postman一樣,搞來搞去,麻煩死了,而且這個是所有人都能看到的,不用每個人都去搞一份。

六、引數設定

有人說了,postman測試的東西可以儲存啊!其實這個一樣的。

開啟檔案管理:

我們看到預設是開啟請求引數快取的,也就是說我們剛才請求過一次,下一次再請求的時候,我們剛才輸入的引數還在,不用每次都輸入很多引數,這麼麻煩。如果是一兩個欄位還好,如果是新增編輯,特別是很多欄位的大頁面的編輯,每次搞一下,辦個小時過去了。這個介面就很方便了,這次新增時你輸入的值,下次還在。你測試的時候只需要改個別地方就可以了,非常非常方便。

到這了,還有人會說,我們很多時候要從請求頭裡面那一些東西,比如token了,userId了,等等。確實,一般是這麼操作的。別慌,我們這個介面檔案測試的的時候一樣可以搞定。

比如,你每次需要從請求頭裡面獲取到使用者id,那麼你可以這裡設定成header,然後輸入userId,然後是userId的具體值。如果你要輸入token,那麼就輸入token和具體的值。至於這個token的值嘛,需要你獲取到之後放到這裡。

這樣看來,這個介面檔案就不止是介面檔案了,它同時也是測試的工具,儲存測試資料的工具。至於術語咱就不bb了,什麼這加那加那的綜合體之類的,沒啥意義。

當然,如果有人想要你這個測試的資料,又不能讓你一個一個的拷貝出來給他,那多難受啊!這個檔案支援4種方式的下載。

七、非實體類引數設定

上面我們給出的介面檔案的請求引數都是物件的,我們當然知道每個欄位什麼意思了,當時如果是單個欄位或者是map呢?用map作為controller的請求引數的非蠢既壞,但是沒辦法,誰讓人家是使用者呢?

這個也很簡單。

@ApiOperation("修改密碼")
    @ApiImplicitParams({
	@ApiImplicitParam(name = "username",value = "賬號" , dataType = "String", paramType = "query"),		
	@ApiImplicitParam(name = "oldPassword",value = "舊密碼" , dataType = "String", paramType = "query"),
	@ApiImplicitParam(name = "newPassword",value = "新密碼" , dataType = "String", paramType = "query")
	})

八、忽略引數

在我們的新增和編輯頁面,經常是編輯只比新增多了一個id,如果此時我們再單獨給新增編輯加一個實體類,其實有一些多餘。此時我們只需要指定對應的欄位忽略掉即可。

@PostMapping("addUser")
@ApiOperation("新增使用者")
@ApiOperationSupport(ignoreParameters = "id") // 忽略掉User中的id屬性,不顯示在檔案中
public void addUser(User user) {
 
}

注意:

ignoreParameters支援以陣列形式新增多個忽略引數
ignoreParameters支援忽略級聯物件的引數,比如User實體類中有個Address型別的屬性addr,那麼如果想要忽略Address的屬性id,那麼只需要設定為ignoreParameters = "addr.id"即可
如果要忽略的引數過多,可以使用includeParameters反向設定

如果是以@RequestBody形式接收引數,那麼ignoreParameters中填寫引數名.要忽略的屬性名即可。

@PostMapping("addUser2")
@ApiOperation("新增使用者2")
@ApiOperationSupport(ignoreParameters = {"user.id", "user.age"})
public void addUser2(@RequestBody User user) {
 
}

注意:

ignoreParameters支援以陣列形式新增多個忽略引數
ignoreParameters支援忽略級聯物件的引數,比如User實體類中有個Address型別的屬性addr,那麼如果想要忽略Address的屬性id,那麼只需要設定為ignoreParameters = "user.addr.id"即可
如果要忽略的引數過多,可以使用includeParameters反向設定

九、生產上關閉knife4j

如果要在生產上關閉knife4j檔案——生產上肯定要關閉的,只要在組態檔中設定:

# 開啟遮蔽檔案資源production: true

如果你的專案中只有一個application.yml,則專案上線時會指定profile,也就是prd的環境,這個時候把遮蔽檔案資源開啟即可;如果是多個application檔案,比如一個基礎的application.yml,然後一個application-dev.yml,一個application-uat.yml,一個application-prd.yml,那麼只要在prd這個檔案中新增上面 的設定即可。

到此這篇關於Knife4j3.0.3整合SpringBoot2.6.4的文章就介紹到這了,更多相關Knife4j整合SpringBoot內容請搜尋it145.com以前的文章或繼續瀏覽下面的相關文章希望大家以後多多支援it145.com!


IT145.com E-mail:sddin#qq.com