Knife4j 是什么?
Knife4j 是一个为 Java 项目生成和管理 API 文档的工具。实际上,它是 Swagger UI 的一个增强工具集,旨在让 Swagger 生成的 API 文档更优雅、更强大。
Knife4j 主要功能
- 美观的 UI:相比于原生 Swagger UI,Knife4j 提供了更加人性化和美观的界面设计。
- 丰富的文档交互功能:支持在线调试、请求参数动态输入、接口排序等。
- 个性化配置:可自定义 API 文档的界面风格,实现文档界面的个性化展示。
为什么要用它?
小伙伴们可能会疑惑,咱这不是一个人就把前后端包办吗?还搞啥 API 文档,是不是多此一举了。其实,我们主要想用的是它的在线调试功能,在前面小节中,小哈在调试接口这块,都是通过 Postman 来进行的,每当测试一个新的接口时,就不得不手动填写请求路径,组装 JSON 入参格式,其实还是比较繁琐的。
有了 Knife4j,因为它支持在线调试,这块的时间就可以省下来了。我们就来看看,如何通过 Knife4j 提升接口调试效率。
整合 Knife4j
添加依赖
在父项目 中(主项目)的 pom.xml
文件中,添加 Knife4j 依赖版本号:
<!-- 版本号统一管理 -->
<properties>
<!-- 依赖包版本 -->
省略...
<knife4j.version>4.3.0</knife4j.version>
</properties>
<!-- 统一依赖管理 -->
<dependencyManagement>
<dependencies>
省略...
<!-- knife4j(API 文档工具) -->
<dependency>
<groupId>com.github.xiaoymin</groupId>
<artifactId>knife4j-openapi2-spring-boot-starter</artifactId>
<version>${knife4j.version}</version>
</dependency>
</dependencies>
</dependencyManagement>
因为 开发的项目都需要调试接口,所以,我们需要在有controller模块中,都需要引入该依赖:
<!-- knife4j -->
<dependency>
<groupId>com.github.xiaoymin</groupId>
<artifactId>knife4j-openapi2-spring-boot-starter</artifactId>
</dependency>
添加配置类
在 xx-web
模块中添加包 config
, 用于统一放置配置类。在该包下新建名为 Knife4jConfig
配置类
配置类完整代码如下:
package com.yanxiaosheng.xx.web.config;
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.EnableSwagger2WebMvc;
/**
* @author: 闫小生
* @date: 2023-08-16 7:53
* @description: Knife4j 配置
**/
@Configuration
@EnableSwagger2WebMvc
public class Knife4jConfig {
@Bean("webApi")
public Docket createApiDoc() {
Docket docket = new Docket(DocumentationType.SWAGGER_2)
.apiInfo(buildApiInfo())
// 分组名称
.groupName("Web 前台接口")
.select()
// 这里指定 Controller 扫描包路径
.apis(RequestHandlerSelectors.basePackage("com.yanxiaosheng.xx.web.controller"))
.paths(PathSelectors.any())
.build();
return docket;
}
/**
* 构建 API 信息
* @return
*/
private ApiInfo buildApiInfo() {
return new ApiInfoBuilder()
.title("xx项目 接口文档") // 标题
.description("Knife4j测试接口") // 描述
.contact(new Contact("闫小生", "https://blog.csdn.net/m0_68207804?type=blog", "ysa0686@163.com")) // 联系人
.version("1.0") // 版本号
.build();
}
}
注意!!!!!!!!!!!!!
RequestHandlerSelectors.basePackage("com.quanxiaoha.weblog.web.controller")
中的包路径,需要改成你实际的controller
包路径,否则会导致接口扫描不到。
上述代码中,通过 @Configuration
指定了 Knife4jConfig
这个类为配置类,同时添加了 @EnableSwagger2WebMvc
注解,该注解作用是启用 Swagger2,定义了一个 Docket
Bean 包含了 Swagger 相关的配置信息。
看看效果
完成上面配置后,重启项目,若控制台出现如下红线标注的日志,则表示 Knife4j
配置完成了:
浏览器访问路径 http://localhost:8080/doc.html
, 就可以看到 api
管理界面了,如下图所示:
大概解释一下 UI 界面的功能点:
-
主页: 文档整体信息一览,包括文档标题、简介、作者、接口统计信息等,也就是
Knife4jConfig
类中buildApiInfo()
方法配置的相关信息; -
分组:实际企业级项目中,可能会分为多个模块、或者很多微服务,分组用于对接口进行分类。
-
Swagger Models : 服务端接口相关的领域模型;
-
文档管理: 这个模块里面可以设置全局参数,比如每次请求在 header 头中统一添加某个参数等;导出
API
文档到本地,以及个性化设置,有兴趣的小伙伴可以自己点进去体验一波:
项目接口:左侧导航栏中会列举出本项目中的所有 controller
类,以及其中的接口。因为当前项目只有一个供测试的 TestController
,效果如下:
可以看到 Knife4j 自动根据我们的 controller
代码,将所有的接口列出来了,包括请求示例、请求参数等。
如何调试接口
假设说,你刚刚开发好了一个新的接口,需要本地调试一下接口是否正常。只需点击左侧 调试 选项,然后填写字段值,在点击发送按钮即可:
返参效果图:
给 controller 添加 Swagger 相关注解
痛点:目前在左侧显示的模块类名,以及接口名称都是代码中本身的英文,也许你当前调试中,能够清晰的知道哪个 controller
类、哪个接口都是干啥的,但是时间一长,接口多了起来,你就会一脸懵逼了,挨,这个 controller
是管理那块的功能的?
为了解决这个问题,Swagger 提供了相关的注解,可以标识模块名称,以及接口名称,并方便的展示在管理界面中。添加方式如下:
-
@Api
: 此注解作用于controller
之上,用于描述相关职责; -
@ApiOperation
: 此注解作用于接口上,用于描述接口干啥的;
添加完上面两个注解后,管理界面的效果图如下:
明显感觉到管理上更加清晰明了了。
除上面两个注解外,我们还可以给入参对象添加 Swagger 相关注解,如下所示:
@ApiModel
: 此注解作用于实体类上,用于描述类;@ApiModelProperty
: 此注解作用于字段上,用于描述字段;
每个字段对应的说明也有了。
生产环境如何屏蔽 Knife4j
很多时候,我们不想项目在生产环境中暴露出所有接口信息,只想在测试环境中联调使用,那么要如何屏蔽该功能呢?
Spring Boot Profile 特性
Profile 是 Spring Boot 中的一项特性,允许你在不同环境中使用不同的配置。这种机制使得我们可以轻松地在不同环境(如开发、测试和生产环境)中使用不同的配置参数。
@Profile
注解
你可以在配置类上添加 @Profile
注解,来控制 Knife4j 是否生效 。只有当指定的 Profile 处于激活状态时,该配置类才会被创建和被使用。代码如下:
@Configuration
@EnableSwagger2WebMvc
@Profile("dev") // 只在 dev 环境中开启
public class Knife4jConfig {
省略...
}
分组功能
前面说到分组,项目接口分会有多个模块,所以,除了在 xx-web
模块中配置 Knife4j 外,还需要在 xx-module-admin
也配置一份,并使用 Knife4j 分组功能将各自的接口隔离开来。
添加依赖、配置类
xx-module-admin
模块和前面的步骤一样,在 pom.xml
添加依赖:
<!-- knife4j -->
<dependency>
<groupId>com.github.xiaoymin</groupId>
<artifactId>knife4j-openapi2-spring-boot-starter</artifactId>
</dependency>
建包 config
, 并创建 Knife4jAdminConfig
配置类,代码如下:
package com.yanxiaosheng.xx.admin.config;
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.EnableSwagger2WebMvc;
/**
* @author: 闫小生
* @date: 2023-08-16 7:53
* @description: Knife4j 配置
**/
@Configuration
@EnableSwagger2WebMvc
@Profile("dev") // 只在 dev 环境中开启
public class Knife4jAdminConfig {
@Bean("adminApi")
public Docket createApiDoc() {
Docket docket = new Docket(DocumentationType.SWAGGER_2)
.apiInfo(buildApiInfo())
// 分组名称
.groupName("Admin 后台接口")
.select()
// 这里指定 Controller 扫描包路径
.apis(RequestHandlerSelectors.basePackage("com.yanxiaosheng.xx.admin.controller"))
.paths(PathSelectors.any())
.build();
return docket;
}
/**
* 构建 API 信息
* @return
*/
private ApiInfo buildApiInfo() {
return new ApiInfoBuilder()
.title("xx项目 接口文档") // 标题
.description("Knife4j测试接口") // 描述
.contact(new Contact("闫小生", "https://blog.csdn.net/m0_68207804?type=blog", "ysa0686@163.com")) // 联系人
.version("1.0") // 版本号
.build();
}
}
注意!!!!!!!!!!!!!
RequestHandlerSelectors.basePackage("com.quanxiaoha.weblog.web.controller")
中的包路径,需要改成你实际的controller
包路径,否则会导致接口扫描不到。
注意类名,和 @Bean
的名称不能和 xx-web模块
中的一样,否则会冲突。然后,改写分组名称,以及包扫描路径,还有 API 相关信息。
完成上述工作后,重启项目,再次访问 API
管理界面,即可看到分组勾选栏中,有前台接口和 Admin 后台接口了,后面查找相关接口,只需先确定是属于前台,还是后台,然后再对应的去查找相关接口,也方便很多: