1.情景展示
開發接口供別人調用或者前后端分離后,前端調后端請求需要提供什么參數,會返回什么樣的結果。如果一對一溝通的話,費時費力,寫接口文檔的話也比較麻煩。
2.效果展示
現在使用knife4j就可以實現以下效果:
點擊調試按鈕,就可以直接配置請求參數,發送請求啦
3 1.9.6版本配置
這是1.9最后一個版本,要想實現這種效果,實現步驟如下:
1.引入jar包
只需要引入這一個jar包就可以了,無需其它jar包。
2.創建一個配置類,比如:Knife4jConfig
3.導包
4.添加注解
以上是三個注解,一個都不能少,在這里需要注意的一點就是:
啟用knif4j使用的注解是:@EnableSwaggerBootstrapUi,而不是@EnableKnife4j
5.創建Docket對象,並注入到spring容器當中
6.設置主頁文檔內容
在配置文件類Knife4jConfig中添加以上兩個方法即可。
4 2.0.4版本配置
1.導包
<!--配置knife4j項目接口文檔--> <dependency> <groupId>com.github.xiaoymin</groupId> <artifactId>knife4j-spring-boot-starter</artifactId> <version>2.0.4</version> </dependency>
說明:2.0.2版本的,只需要把上面jar包的版本號改成2.0.2即可,下面的配置一模一樣。
只需要引入這一個jar包就可以了,無需其它jar包。
2.創建一個配置類,比如:Knife4jConfig(配置文件類最好創建一個config/conf包,方便統一管理)
import com.github.xiaoymin.knife4j.spring.annotations.EnableKnife4j; import io.swagger.annotations.ApiOperation; 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.service.Contact; import springfox.documentation.spi.DocumentationType; import springfox.documentation.spring.web.plugins.Docket; import springfox.documentation.swagger2.annotations.EnableSwagger2; /** * 項目接口文檔配置(swagger) * @description: 使用knife4j需要一個swagger的配置類 * @author: Marydon * @date: 2020年08月11日 0011 9:22 */ @Configuration // 必須啟用swagger @EnableSwagger2 @EnableKnife4j // swagger文檔配置只在指定環境可訪問(該注解的值對應的是application.yml文件中的spring.profiles.active的值) // 支持使用!,比如:!prod表示非生產環境 // @Profile({"dev","test","jc"}) public class Knife4jConfig { /* * 創建連接的包信息 * @param: 方法名稱隨便起,雖然它的名字會被作為Bean對象的名字注入spring容器 * @date: 2020年08月11日 0011 9:51 * @param: * @return: springfox.documentation.spring.web.plugins.Docket 返回創建狀況 */ @Bean public Docket defaultApi2() { return new Docket(DocumentationType.SWAGGER_2) // 選擇swagger2版本 .useDefaultResponseMessages(false) // 接口文檔的基本信息 .apiInfo(apiInfo()) .select() // 這里指定Controller掃描包路徑(項目路徑也行) // 方式一:配置掃描:所有想要在swagger界面統一管理的接口,都必須在此包下 // .apis(RequestHandlerSelectors.basePackage("com.company.project.web.controller.entrance")) // 方式二:只有當方法上有@ApiOperation注解時,才能生成對應的接口文檔 .apis(RequestHandlerSelectors.withMethodAnnotation(ApiOperation.class)) // 路徑使用any風格(指定所有路徑) .paths(PathSelectors.any()) .build(); } /* * 設置文檔信息主頁的內容說明 * @date: 2020年08月11日 0011 9:52 * @param: * @return: springfox.documentation.service.ApiInfo 文檔信息 */ private ApiInfo apiInfo() { return new ApiInfoBuilder() .title("接口項目 后台服務API接口文檔") .description("服務相關接口(knife4j)") // 服務Url(網站地址) .termsOfServiceUrl("http://localhost:8080/") .contact(new Contact("Marydon",null,"marydon20170307@163.com")) .version("1.0") .build(); } }
啟動項目,訪問:http://IP:端口號/程序名稱/doc.html即可,顯示主頁。
5.注解基本用法
@Api():用於類的說明,准確的來說用於controller,表示這個類是一個swagger資源
對應的是:一個Controller
注意:tags屬性必須顯式聲明,否者無法修改小組的顯示名稱
舉例:
實際效果:
未生效(因為沒有聲明:tags=)
@ApiOperation():用於方法的說明,表示這是一個HTTP請求
對應的是controller里的方法
2020-12-16
這里需要注意的是:
@PostMapping對應的post請求,反映到API上就是post請求;
@GetMapping對應的get請求,反映到API上就是get請求;
@RequestMapping如果沒有指定具體請求方式
API文檔如下:
它會給你生出7種不同的請求方式,API本身沒錯
實際上,我們使用@RequestMapping的真實目的,也許是:想讓該接口既支持get請求,也支持post請求,那我們可以做出限定。
這樣,就OK啦
有一個奇怪的地方就是:
knife4j生成的所有接口方法,所對應的響應數據類型都是:*/*,當我在Mapping注解里指定可接受的數據類型后,API上卻成了響應數據類型的值。
請求的數據類型是不會受到影響的,knife4j是根據方法入參來自動判斷請求的數據類型的,舉個栗子:
上面我們用的是@RequestBody,那knife4j就知道請求數據類型為:application/json;
當我們改用@RequestParam時,它會識別為:application/x-www-form-urlencoded。
等等,上面兩種是我實際測試出來的,其它的識別方式就不得而知了。
2020-12-17
今天,發現:knife4j會將header和produces的值都塞到響應數據類型里面。比如:
@RequestMapping(value = "clear", method = {RequestMethod.GET, RequestMethod.POST}, headers = {"Accept=text/pain"}, produces = "text/html;charset=UTF-8")
所以,當我們想要這里展示出具體的響應數據類型的話,在Mapping注解添加produces屬性並設值即可。
@ApiOperationSupport():(knife4j增加特性)用於接口方法排序,作者信息描述等
@ApiImplicitParams():參數列表說明
如果不是用實體類接收入參的話,存在多個入參可以用該注解說明
@ApiParam:對單個參數的說明
如果不是用實體類接收入參的話,存在一個或者多個入參也可以用該注解進行逐個說明
@ApiModel():用於描述一個數據模型的信息,即我們常用的實體、VO類、DTO類等描述
在接口入參用實體類接收時,通常用該注解對實體類進行說明,一般與@ApiModelProperty結合使用,與上面兩個參數注解達到的效果是一樣的。
@ApiModelProperty():用於描述數據模型的屬性信息
對應的是方法名的請求入參
@ApiIgnore:自動生成接口說明時忽略,可用於類、方法、方法入參
@ApiResponses:響應狀態描述(在控制類下方,首個方法名上方)
對應到文檔上是:
6 2.0.6以后的版本
使用該版本,必須使用@EnableSwagger2WebMvc這一個注解。
該配置類里的兩個方法
就可以合並成一個方法啦
@Bean(value = "defaultApi2") public Docket defaultApi2() { Docket docket = new Docket(DocumentationType.SWAGGER_2) // 選擇swagger2版本 // 接口文檔的基本信息 .apiInfo(new ApiInfoBuilder() .title("接口項目 后台服務API接口文檔") .description("服務相關接口(knife4j)") // 服務Url(網站地址) .termsOfServiceUrl("http://127.0.0.1:8080/") .contact(new Contact("Marydon",null,"marydon20170307@163.com")) .version("1.0") .build()) //分組名稱,不配置的話,默認值為:default .groupName("2.X版本") .select() // 這里指定Controller掃描包路徑(項目路徑也行) // 方式一:配置掃描:所有想要在swagger界面統一管理的接口,都必須在此包下 // .apis(RequestHandlerSelectors.basePackage("com.baidu.zhidao.web.controller.entrance")) // 方式二:只有當方法上有@ApiOperation注解時,才能生成對應的接口文檔 .apis(RequestHandlerSelectors.withMethodAnnotation(ApiOperation.class)) // 路徑使用any風格(指定所有路徑) .paths(PathSelectors.any()) .build(); return docket; }
PS:不合並也是可以噠。
說明:
使用Knife4j2.0.6及以上的版本,Spring Boot的版本必須大於等於2.2.x
需要注意的是:
當knife4j<=1.9.6時,它是knife4j的前身,叫做:swagger-bootstrap-ui,必須用注解@EnableSwaggerBootstrapUi+@EnableSwagger2;
不僅支持swagger-bootstrap-ui,原始的swagger-ui還是可以使用的,訪問地址:
http://${host}:${port}/swagger-ui.html
當2.0.0<=knife4j<=2.0.5時,必須用注解@EnableKnife4j+@EnableSwagger2;
當2.0.6<=knife4j<=2.0.8時,必須使用注解@EnableSwagger2WebMvc。
當knife4j>1.9.6時,已經不支持swagger-ui了。
7.文檔設置訪問權限控制
一般情況下,我們在正式環境下是要屏蔽接口文檔的,只有在非生產環境(比如:開發環境、測試環境)下才允許訪問,如何實現?
可在application.properties/application.yml文件中添加以下配置。
禁用文檔
properties文件:knife4j.production=true
yml文件如下:
重啟服務,此時,再次訪問doc.html,將是這個樣子:
啟用文檔:將值改為false即可(表示的含義是:非生產環境)
這樣一來,在打包的時候,如果允許訪問,就將其值改成false;否則,就改成true。
這種方式不夠智能,打包的時候,我們還需要記得改值,太麻煩了,還有更簡單的一種。
通過注解@Profile來實現
可以配置多個訪問環境,中間使用逗號隔開;
也可以使用!,!prod,就表示只要profile的值不等於prod,就可以訪問得到文檔;
@profile里的值對應的是主配置文件application.yml中spring.profiles.active的值,如下圖所示:
spring.profiles.active的值的值其實是很隨意的,跟開發環境、生產環境、預演環境、生產環境等沒有半毛錢關系,只不過是大家習慣於這樣使用,方便區分罷了。
按照這種方式,基本上就已經滿足普通開發者的需求了,也相當於實現了動態配置。
說明:
如果采取這種方式,下面的值必須是false或者直接刪掉該配置。
然而這種方式對於我來說還是太傻了,隨着公司產品的推廣,一個地方會添加一個配置文件,每個地方又都有正式和測試之分;
這樣的話,每個地方測試的時候,我得改下配置啟用;在正式上線的時候再禁用,太麻煩!怎么辦,有沒有一勞永逸的辦法?
通過在pom.xml中配置多個profile實現
在properties標簽添加自定義屬性isProduction,名稱隨意,值是固定的:true/false
在主配置文件application引入該標簽的值即可
說明:yml文件引入pom.xml的值使用@標簽名@,properties文件引入pom.xml的值使用${標簽名}
這樣,我在打包的時候,就不需要手動去修改production的值,而是通過切換環境通過maven插件,將對應的值塞到主配置文件中。
說明:
這種方式,適用於大量配置文件,且需要來回切換環境的需求;
通過這種配置方式,就無需再配置@Profile注解了,否則就有點畫蛇添足了。
8.文檔通過密碼訪問
通過上面,我們只能控制環境來間接控制文檔是否可訪問,只要你能訪問該接口文檔,那么別人也一樣可以訪問得到,還不夠安全。
如果有更高的安全需求,我們還可以為文檔添加訪問密碼。
這樣,當我們再次訪問該文檔時,就需要輸入用戶名和密碼才能訪問啦。
9.自定義Footer
修改這個顯示內容
前提:knife4j>=2.0.8
第一步:必須開啟增強功能
第二步:設置Footer
第三步:修改knife4j的配置類,比如:我上面叫做Knife4jConfig.java
注入對象:OpenApiExtensionResolver
// 自定義footer需要用到 @Resource private OpenApiExtensionResolver openApiExtensionResolver;
Docket增加擴展方法
new Docket(DocumentationType.SWAGGER_2) // 擴展屬性(footer) .extensions(openApiExtensionResolver.buildSettingExtensions());
效果展示:
10.分組排序
2020-12-16
文檔上,每一項對應的是一個Controller,每一個controller相當於一個小組,有時候我們會想給它們排排順序,怎么搞?
要想實現這個個性化的需求,需要滿足三個條件:
第一,knife4j>=2.0.8;
第二,使用注解@ApiSupport;
說明:每個控制層的order值,必須大於0,且最好間隔10以上。
第三,開啟增強功能。
增強功能需要通過配置yml配置文件開啟:
knife4j: enable: true
11.接口排序
每個控制器可能會對外公開多個接口,多個接口如何自定義排序呢?
使用注解@ApiOperationSupport;
其它兩個條件,同上,缺一不可。