SpringBoot整合knife4j實(shí)踐
SpringBoot 整合knife4j
Knife4j是一款基于Swagger 2的在線API文檔框架
在Spring Boot中,使用此框架時(shí),需要:
- 添加依賴
- 在配置文件(`application.properties`)中開(kāi)啟增強(qiáng)模式
- 編寫配置類(代碼相對(duì)固定,建議CV)
引入knife4j
添加依賴
<dependency>
<groupId>com.github.xiaoymin</groupId>
<artifactId>knife4j-spring-boot-starter</artifactId>
<version>3.0.3</version>
</dependency>創(chuàng)建 Swagger 配置依賴
package com.yolo.knife4j.config;
import io.swagger.annotations.Api;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Import;
import springfox.bean.validators.configuration.BeanValidatorPluginsConfiguration;
import springfox.documentation.builders.*;
import springfox.documentation.service.*;
import springfox.documentation.spi.DocumentationType;
import springfox.documentation.spring.web.plugins.Docket;
import springfox.documentation.swagger2.annotations.EnableSwagger2WebMvc;
@Slf4j
@Configuration
@EnableSwagger2WebMvc
// 對(duì)JSR303提供支持
@Import(BeanValidatorPluginsConfiguration.class)
public class Knife4jConfig {
@Value("${spring.application.name}")
private String applicationName;
@Bean
public Docket defaultApi() {
return new Docket(DocumentationType.SWAGGER_2)
.apiInfo(apiInfo())
.groupName(applicationName)
.select()
// 添加@Api注解才顯示
.apis(RequestHandlerSelectors.withClassAnnotation(Api.class))
// 這里指定Controller掃描包路徑
// .apis(RequestHandlerSelectors.basePackage("com.yolo"))
.paths(PathSelectors.any())
.build();
}
/**
* swagger-api接口描述信息
*/
private ApiInfo apiInfo() {
return new ApiInfoBuilder()
.title("API文檔")
.description("API文檔")
.contact(
new Contact(
"yolo",
"https://gitee.com/huanglei1111",
"2936412130@qq.com"
)
)
.version("1.0.0")
.build();
}
}application.yml配置文件
# https://doc.xiaominfo.com/knife4j
knife4j:
# 開(kāi)啟增強(qiáng)配置
enable: true
# 是否開(kāi)啟生產(chǎn)環(huán)境屏蔽 true:關(guān)閉swagger,false:開(kāi)啟swagger
production: false
basic:
# 是否開(kāi)啟認(rèn)證
enable: false
# Basic認(rèn)證用戶名
username: admin
# Basic認(rèn)證密碼
password: 123456
spring:
application:
name: test-knife4j注解
@Api(tags = {“用戶操作”})
加在controller類上
tags表示該類的標(biāo)簽,在頁(yè)面會(huì)獨(dú)立顯示一個(gè)菜單
@ApiOperation(value = “保存用戶”, notes = “保存時(shí),ID由數(shù)據(jù)庫(kù)生成,無(wú)需填寫,有則忽略”, tags = “保存”)
加在相應(yīng)的請(qǐng)求處理方法上
value表示該方法的說(shuō)明
notes相當(dāng)于對(duì)該方法的詳細(xì)說(shuō)明,也就是更加完整的描述
tags 表示標(biāo)簽,,在頁(yè)面會(huì)獨(dú)立顯示一個(gè)菜單
@ApiImplicitParam(name = “id”, value = “用戶ID”, defaultValue = “1”)
方法只有一個(gè)基本類型參數(shù)時(shí)加在方法上。方法有多個(gè)參數(shù)時(shí)加在@ApiImplicitParams內(nèi)
name 參數(shù)中屬性的名字
value 對(duì)這個(gè)屬性的描述
defaultValue 默認(rèn)值,這個(gè)還是有必要填寫的,在頁(yè)面進(jìn)行請(qǐng)求時(shí),會(huì)自動(dòng)填充
@ApiImplicitParams(value = {})
用在請(qǐng)求方法上
這個(gè)注解必須和@ApiImplicitParam配合使用
當(dāng)請(qǐng)求方法中的請(qǐng)求參數(shù)很多的時(shí)候,例如saveUser(String username, Integer age, Date birthday, String phone)
@ApiParam(value = “當(dāng)前頁(yè)”, defaultValue = “1”)
加在請(qǐng)求方法的普通參數(shù)上
value的值是對(duì)該參數(shù)的說(shuō)明
與@ApiImplicitParam使用的效果等同,根據(jù)個(gè)人喜好進(jìn)行使用
@ApiModel(value = “用戶信息”)
加在請(qǐng)求方法的對(duì)象類上
value 對(duì)該對(duì)象參數(shù)的描述
例如有一個(gè)請(qǐng)求方法save(UserDTO userDTO), 則需要加在UserDTO這個(gè)類上面(可以參照下面的示例)
@ApiModelProperty(value = “用戶ID”, example = “1”)
加在請(qǐng)求方法的參數(shù)對(duì)象的屬性上
value 對(duì)該屬性的描述
example 屬性的示例值,在頁(yè)面會(huì)自動(dòng)填充該值
@ApiIgnore:注解類、參數(shù)、方法,注解后將不在Swagger UI中顯示案例
package com.yolo.knife4j.controller;
import cn.hutool.core.collection.ListUtil;
import com.yolo.knife4j.base.ResultVo;
import com.yolo.knife4j.dto.UserAddRequest;
import com.yolo.knife4j.vo.StudentVO;
import com.yolo.knife4j.vo.UserVO;
import io.swagger.annotations.*;
import org.springframework.web.bind.annotation.*;
import javax.validation.Valid;
import java.util.Date;
@ApiResponses(value = {
@ApiResponse(code = 200, message = "接口返回成功狀態(tài)"),
@ApiResponse(code = 500, message = "接口返回未知錯(cuò)誤,請(qǐng)聯(lián)系開(kāi)發(fā)人員調(diào)試")
})
@Api(tags = "用戶")
@RestController
@RequestMapping("/user")
public class UserController {
@ApiOperation(value = "保存用戶", notes = "簡(jiǎn)單傳參")
@PostMapping("/add")
public ResultVo<Object> add(@RequestBody @Valid UserAddRequest userAddRequest) {
return ResultVo.builder().build().setCode(200).setSuccess(true)
.setTime(new Date()).setMsg("保存用戶成功").setData(userAddRequest);
}
@ApiOperation(value = "保存用戶2", notes = "復(fù)雜傳參")
@PostMapping("/add2")
public ResultVo<Object> add2(@RequestBody @Valid UserAddRequest userAddRequest) {
return ResultVo.builder().build().setCode(200).setSuccess(true)
.setTime(new Date()).setMsg("保存用戶成功").setData(userAddRequest);
}
@GetMapping("/list")
@ApiOperation(value = "查找用戶列表", notes = "根據(jù)id查找單個(gè)用戶")
public ResultVo<Object> list(@RequestParam @ApiParam(value = "當(dāng)前頁(yè)", defaultValue = "1") Integer pageNum,
@RequestParam @ApiParam(value = "頁(yè)大小", defaultValue = "10") Integer pageSize) {
UserVO vo = new UserVO();
StudentVO studentVO = StudentVO.builder().build().setAddress("wuhan").setCode(2);
vo.setStudentVOS(ListUtil.of(studentVO));
return ResultVo.builder().build().setCode(200).setSuccess(true)
.setTime(new Date()).setMsg("查找用戶列表").setData(vo);
}
@DeleteMapping("/{id}")
@ApiOperation(value = "刪除用戶", notes = "刪除后無(wú)法恢復(fù)")
@ApiImplicitParam(name = "id", value = "用戶ID", defaultValue = "1")
public ResultVo<Object> delete(@PathVariable(name = "id") Long id) {
return ResultVo.builder().build().setCode(200).setSuccess(true)
.setTime(new Date()).setMsg("刪除用戶");
}
}響應(yīng)參數(shù)
package com.yolo.knife4j.base;
import com.fasterxml.jackson.annotation.JsonFormat;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Data;
import lombok.NoArgsConstructor;
import lombok.experimental.Accessors;
import java.io.Serializable;
import java.util.Date;
@Data
@Builder
@Accessors(chain = true)
@ApiModel("響應(yīng)參數(shù)")
@AllArgsConstructor
@NoArgsConstructor
public class ResultVo<T> implements Serializable {
private static final long serialVersionUID = -8054007511410819665L;
@ApiModelProperty(value = "響應(yīng)狀態(tài)碼", example = "1", dataType = "Integer")
private int code;
// 是否成功標(biāo)識(shí).true表示成功,false表示失敗
@ApiModelProperty("success標(biāo)識(shí),true表示成功,false表示失敗")
private boolean success;
// 操作成功時(shí)需要響應(yīng)給客戶端的響應(yīng)數(shù)據(jù)
@ApiModelProperty("響應(yīng)信息")
private String msg;
@ApiModelProperty("響應(yīng)數(shù)據(jù)")
private T data;
@ApiModelProperty("當(dāng)前時(shí)間")
@JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss", timezone = "GMT+8")
private Date time;
}tips: http://127.0.0.1:8080/doc.html
這里端口,就是你運(yùn)行項(xiàng)目的端口

knife4j增強(qiáng)功能
springboot 中 knife4j的完整參數(shù)如下:
knife4j:
enable: true
documents:
-
group: 2.X版本
name: 接口簽名
locations: classpath:sign/*
setting:
language: zh-CN
enableSwaggerModels: true
enableDocumentManage: true
swaggerModelName: 實(shí)體類列表
enableVersion: false
enableReloadCacheParameter: false
enableAfterScript: true
enableFilterMultipartApiMethodType: POST
enableFilterMultipartApis: false
enableRequestCache: true
enableHost: false
enableHostText: 192.168.0.193:8000
enableHomeCustom: true
homeCustomLocation: classpath:markdown/home.md
enableSearch: false
enableFooter: false
enableFooterCustom: true
footerCustomContent: Apache License 2.0 | Copyright 2019-[浙江八一菜刀股份有限公司](https://gitee.com/xiaoym/knife4j)
enableDynamicParameter: false
enableDebug: true
enableOpenApi: false
enableGroup: true
cors: false
production: false
basic:
enable: false
username: test
password: 12313接口添加作者
添加作者有倆種方式
- 在方法上使用注解
@ApiOperationSupport(author = "yolo-test") - 在controller類上使用注解
@ApiSupport(author = "yolo-controller")
如果在方法上使用了注解,并且也在類上使用了注解,那么最后的展示結(jié)果以方法上的注解為準(zhǔn)

資源屏蔽
當(dāng)我們?cè)谏森h(huán)境的時(shí)候不想顯示接口文檔,由于 Knife4j 基于 Servlet 體系提供了過(guò)濾 Filter 功能,所以就不需要我們?cè)偃ピ燧喿恿耍苯邮褂眉纯?/p>
knife4j: # 開(kāi)啟增強(qiáng)配置 enable: true # 是否開(kāi)啟生產(chǎn)環(huán)境屏蔽 true:關(guān)閉swagger,false:開(kāi)啟swagger production: true
然后重啟項(xiàng)目

訪問(wèn)頁(yè)面加權(quán)控制
針對(duì)Swagger的資源接口,Knife4j提供了簡(jiǎn)單的Basic認(rèn)證功能
簡(jiǎn)單點(diǎn)說(shuō),指定一個(gè)用戶名和密碼,訪問(wèn) Swagger 文檔需要驗(yàn)證登錄名和密碼,驗(yàn)證通過(guò)之后才能正常訪問(wèn)
如果用戶開(kāi)啟了 basic (knife4j.basic.enable = true)認(rèn)證功能,但是沒(méi)有指定 username 和password,那么 knife4j 提供了一組默認(rèn)的用戶名密碼
admin/123321
knife4j:
# 開(kāi)啟增強(qiáng)配置
enable: true
# 是否開(kāi)啟生產(chǎn)環(huán)境屏蔽 true:關(guān)閉swagger,false:開(kāi)啟swagger
production: false
basic:
# 是否開(kāi)啟認(rèn)證
enable: true
# Basic認(rèn)證用戶名
username: admin
# Basic認(rèn)證密碼
password: 123456如果開(kāi)啟生產(chǎn)環(huán)境屏蔽了,開(kāi)啟basic認(rèn)證是不生效的

接口排序
@ApiOperationSupport注解中增加了 order 字段,用于接口排序。在使用此注解之前需要開(kāi)啟增強(qiáng)功能
分組排序
分組,顧名思義,就是多個(gè) controller 之間的排序,開(kāi)發(fā)者可以通過(guò)注解實(shí)現(xiàn)每個(gè)controller 之間的排序,實(shí)現(xiàn)這個(gè)功能的注解一共有三個(gè),具體如下
@ApiSupport
@RestController @RequestMapping(value = "/test") @ApiSupport(author = "yolo-controller",order = 999) @Api(tags = "測(cè)試swagger") public class Knife4jTestController
@ApiSort
@RestController @RequestMapping(value = "/test") @ApiSort(value = 999) @Api(tags = "測(cè)試swagger") public class Knife4jTestController
@Api
@RestController @RequestMapping(value = "/test") @Api(tags = "測(cè)試swagger",position = 999) public class Knife4jTestController
Tips:
- 這三個(gè)注解是存在優(yōu)先級(jí)的,也就是說(shuō),當(dāng)同時(shí)使用時(shí),只會(huì)有一個(gè)注解生效,所以在使用的時(shí)候需要特別注意。優(yōu)先級(jí)規(guī)則如下
- @ApiSupport > @ApiSort>@Api
請(qǐng)求參數(shù)緩存
我們?cè)谡{(diào)試接口的時(shí)候,有的接口會(huì)有很多參數(shù),當(dāng)我們好不容易填好了所有的參數(shù),由于我們不小心關(guān)閉了頁(yè)面,下次再調(diào)試的時(shí)候發(fā)現(xiàn)還需要再次將參數(shù)輸入一遍,心態(tài)會(huì)爆炸吧,所以 knife4j 在文檔管理中增加了一個(gè)選項(xiàng):開(kāi)啟請(qǐng)求參數(shù)緩存

Tips:
倆種情況會(huì)失效
- 1、 @ApiModelProperty 注解中添加 example (屬性的示例值)屬性,那么, knife4j 將不會(huì)使用緩存,使用的是后端指定的 example
- 2、當(dāng)域名發(fā)生改變時(shí),所有緩存將會(huì)失效
過(guò)濾請(qǐng)求參數(shù)
我們?cè)陂_(kāi)發(fā)過(guò)程中,經(jīng)常會(huì)遇到這樣的一個(gè)問(wèn)題,新增和修改接口,修改接口需要傳遞修改的記錄id,但是新增則不需要,而后端往往會(huì)將修改和新增的入?yún)?duì)象設(shè)置為一個(gè)對(duì)象,那么這個(gè)對(duì)象中必然會(huì)存在 id 字段,這就會(huì)對(duì)新增造成誤導(dǎo)
所以,knife4j 支持了請(qǐng)求參數(shù)的過(guò)濾(忽略),實(shí)現(xiàn)方式也是非常的簡(jiǎn)單,使用自定義增強(qiáng)注解ApiOperationSupport中的ignoreParameters屬性,可以強(qiáng)制忽略要顯示的參數(shù)
這里表單和json格式過(guò)濾參數(shù)是不一樣的
我們先看表單格式
@ApiModel("用戶信息")
@Getter
@Setter
@ToString
public class UserDTO {
@ApiModelProperty(value = "用戶id")
private Long id;
@ApiModelProperty(value = "用戶名",example = "李雷")
private String username;
@ApiModelProperty(value = "性別",example = "男")
private String gender;
@ApiModelProperty(value = "手機(jī)號(hào)碼",example = "18888888888")
private String phone;
@ApiModelProperty(value = "用戶收貨地址信息")
private UserAddressDTO userAddressDTO;
}
@Getter
@Setter
@ToString
public class UserAddressDTO {
@ApiModelProperty(value = "收獲地址的記錄id")
private Long id;
@ApiModelProperty(value = "省")
private String province;
@ApiModelProperty(value = "市")
private String city;
@ApiModelProperty(value = "區(qū)")
private String district;
@ApiModelProperty(value = "詳細(xì)地址")
private String addr;
}
@PostMapping(value = "/saveUser")
@ApiOperation("新增用戶信息-表單")
@ApiOperationSupport(author = "yolo",ignoreParameters = {"id","userAddressDTO.id"})
public String saveUser(UserDTO userDTO){
System.out.println("前端傳遞的用戶信息:"+ userDTO);
return "save success";
}
@PostMapping(value = "/updateUser")
@ApiOperation("編輯用戶信息")
@ApiOperationSupport(author = "yolo")
public String updateUser( UserDTO userDTO){
System.out.println("前端傳遞的用戶信息:"+ userDTO);
return "edit success";
}在過(guò)濾字段的時(shí)候,第一層我們只要填寫對(duì)象中的屬性名即可,但如果需要過(guò)濾第二層,根據(jù)忽略規(guī)則中的第二條,我們?cè)?UserDTO 對(duì)象中引入 UserAddressDTO 對(duì)象:private UserAddressDTO userAddressDTO; 我們還需要忽略 UserAddressDTO 對(duì)象中的 id 屬性,那么需要填上 userAddressDTO.id ,其中 userAddressDTO 要與 UserDTO 對(duì)象中的 UserAddressDTO 屬性名一致
新增操作沒(méi)有id

編輯操作

JSON格式忽略
專業(yè)說(shuō)法是:實(shí)例名.屬性名,以新增用戶為例,我們需要過(guò)濾用戶id,那么寫法就是:userDTO.id,其中 userDTO 為 saveUser() 的 參數(shù)名
@PostMapping(value = "/saveUser")
@ApiOperation("新增用戶信息")
@ApiOperationSupport(author = "yolo",ignoreParameters = {"userDTO.id","userDTO.userAddressDTO.id"})
public String saveUser(@RequestBody UserDTO userDTO){
System.out.println("前端傳遞的用戶信息:"+ userDTO);
return "save success";
}禁用調(diào)試
knife4j:
enable: true
setting:
enableDebug: falseenableDebug:該屬性是一個(gè)Boolean值,代表是否啟用調(diào)試功能,默認(rèn)值為true(代表開(kāi)啟調(diào)試),如果要禁用調(diào)試,該值設(shè)為false
同樣,此操作也需要開(kāi)發(fā)者在創(chuàng)建Docket邏輯分組對(duì)象時(shí),通過(guò)Knife4j提供的工具對(duì)象OpenApiExtensionResolver將擴(kuò)展屬性進(jìn)行賦值

禁用搜索框
發(fā)者如果想要禁用Ui界面中的搜索功能,需要通過(guò)增強(qiáng)屬性進(jìn)行配置,此功能需要開(kāi)啟增強(qiáng)功能
knife4j:
enable: true
setting:
enableSearch: falseenableSearch:該屬性是一個(gè)Boolean值,代表是否啟用搜索功能,默認(rèn)值為true(代表開(kāi)啟搜索),如果要禁用搜索,該值設(shè)為false
同樣,此操作也需要開(kāi)發(fā)者在創(chuàng)建Docket邏輯分組對(duì)象時(shí),通過(guò)Knife4j提供的工具對(duì)象OpenApiExtensionResolver將擴(kuò)展屬性進(jìn)行賦值。具體的代碼實(shí)現(xiàn)請(qǐng)參考禁用調(diào)試和自定義主頁(yè)內(nèi)容,我這里就不重復(fù)了。
總結(jié)
以上為個(gè)人經(jīng)驗(yàn),希望能給大家一個(gè)參考,也希望大家多多支持腳本之家。
相關(guān)文章
Mybatis注解開(kāi)發(fā)@Select執(zhí)行參數(shù)和執(zhí)行sql語(yǔ)句的方式(最新詳解)
@Select 是 Mybatis 框架中的一個(gè)注解,用于執(zhí)行 SQL 查詢語(yǔ)句,并把查詢結(jié)果映射到指定的 Java 對(duì)象中,這篇文章主要介紹了Mybatis注解開(kāi)發(fā)@Select執(zhí)行參數(shù)和執(zhí)行sql語(yǔ)句的方式,需要的朋友可以參考下2023-07-07
Java版仿QQ驗(yàn)證碼風(fēng)格圖片驗(yàn)證碼
這篇文章主要為大家分享了java圖片驗(yàn)證碼實(shí)例代碼,感興趣的小伙伴們可以參考一下2016-04-04
基于Spring Security前后端分離的權(quán)限控制系統(tǒng)問(wèn)題
本文給大家分享基于Spring Security前后端分離的權(quán)限控制系統(tǒng)問(wèn)題,需要了解權(quán)限如何加載,權(quán)限匹配規(guī)則和登錄的實(shí)現(xiàn)代碼,對(duì)Spring Security權(quán)限控制系統(tǒng)相關(guān)知識(shí)感興趣的朋友一起看看吧2021-06-06
MybatisPlus字段自動(dòng)填充&樂(lè)觀鎖的方法實(shí)現(xiàn)
MyBatis-Plus提供了便捷的自動(dòng)填充功能,可用于自動(dòng)處理創(chuàng)建時(shí)間、更新時(shí)間等字段,本文來(lái)介紹一下MybatisPlus字段自動(dòng)填充&樂(lè)觀鎖的方法實(shí)現(xiàn),感興趣的可以了解一下2025-08-08
SpringBoot Admin使用及心跳檢測(cè)原理分析
這篇文章主要介紹了SpringBoot Admin使用及心跳檢測(cè)原理分析,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2021-11-11
java學(xué)習(xí)之JVM運(yùn)行時(shí)常量池理解
這篇文章主要介紹了java學(xué)習(xí)之JVM運(yùn)行時(shí)常量池理解,對(duì)常量池的好處以及基本類型的包裝類常量池等作了簡(jiǎn)要分析,有需要的朋友可以借鑒參考下2021-09-09

