一. 简介
knife4j是为Java MVC框架集成Swagger生成Api文档的增强解决方案,前身是swagger-bootstrap-ui,取名kni4j是希望它能像一把匕首一样小巧,轻量,并且功能强悍!
gitee地址:https://gitee.com/xiaoym/knife4j
官方文档:https://doc.xiaominfo.com/
效果演示:http://knife4j.xiaominfo.com/doc.html
是一个集Swagger2 和 OpenAPI3为一体的增强解决方案
对于当前最新的Spring Boot 3有以下注意
- Spring Boot 3 只支持OpenAPI3规范
- Knife4j提供的starter已经引用springdoc-openapi的jar,开发者需注意避免jar包冲突
- JDK版本必须 >= 17
作用
该UI增强包主要包括两大核心功能:文档说明 和 在线调试
- 文档说明:根据Swagger的规范说明,详细列出接口文档的说明,包括接口地址、类型、请求示例、请求参数、响应示例、响应参数、响应码等信息,使用swagger-bootstrap-ui能根据该文档说明,对该接口的使用情况一目了然。
- 在线调试:提供在线接口联调的强大功能,自动解析当前接口参数,同时包含表单验证,调用参数可返回接口响应内容、headers、Curl请求命令实例、响应时间、响应状态码等信息,帮助开发者在线调试,而不必通过其他测试工具测试接口是否正确,简介、强大。
- 个性化配置:通过个性化ui配置项,可自定义UI的相关显示信息
- 离线文档:根据标准规范,生成的在线markdown离线文档,开发者可以进行拷贝生成markdown接口文档,通过其他第三方markdown转换工具转换成html或pdf,这样也可以放弃swagger2markdown组件
- 接口排序:自1.8.5后,ui支持了接口排序功能,例如一个注册功能主要包含了多个步骤,可以根据swagger-bootstrap-ui提供的接口排序规则实现接口的排序,step化接口操作,方便其他开发者进行接口对接
优势
knife4j 是 Swagger 生成 API 文档的增强解决方案,knife4j 对原生 swagger 的增强体现在:
- 提供了新的一套 Web 页面,更符合绝大多数人的使用习惯和审美;
- 补充了一些注解,扩展了原生 Swagger 的功能;
- 提供了动态字段注释功能来实现 Map 来接收参数这个的接口文档生成;
- 忽略参数属性来实现同一个实体类对不同接口生成不同的文档等诸如此类的小改进。
二. 基本使用
1. SpringMVC集成knife4j
1> 依赖引用
<!--引入knife4j-->
<dependency>
<groupId>com.github.xiaoymin</groupId>
<artifactId>knife4j-spring</artifactId>
<version>3.0.3</version>
</dependency>
<dependency>
<groupId>com.github.xiaoymin</groupId>
<artifactId>knife4j-spring-ui</artifactId>
<version>3.0.3</version>
</dependency>
2> 创建配置文件(核心为Swagger)
创建配置文件Knife4jConfig.java
package com.nianxi.knife4j.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.spi.DocumentationType;
import springfox.documentation.spring.web.plugins.Docket;
import springfox.documentation.swagger2.annotations.EnableSwagger2;
@Configuration
@EnableSwagger2
public class Knife4jConfig {
//配置默认的接口
@Bean
public Docket defaultApi() {
return new Docket(DocumentationType.SWAGGER_2)
.apiInfo(groupApiInfo())
.groupName("默认接口")
.select()
.apis(RequestHandlerSelectors.basePackage("com.nianxi.knife4j.controller"))
.paths(PathSelectors.any())
.build();
}
//配置分组
private ApiInfo groupApiInfo(){
return new ApiInfoBuilder()
.title("swagger-bootstrap-ui很棒~~~!!!")
.description("swagger-bootstrap-ui-demo RESTful APIs")
.termsOfServiceUrl("http://www.group.com/")
.version("1.0")
.build();
}
}
3> 配置静态文件
由于knife4j是通过webjar的方式提供服务,因此对外访问的doc.html
需要在我们的mvc环境中配置静态目录,否则会出现404,在spring.xml
主容器的配置文件中配置,
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:mvc="http://www.springframework.org/schema/mvc"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/mvc https://www.springframework.org/schema/mvc/spring-mvc.xsd">
<mvc:resources location="classpath:/META-INF/resources/" mapping="doc.html"/>
<mvc:resources location="classpath:/META-INF/resources/webjars/" mapping="/webjars/**"/>
</beans>
4> 配置web.xml文件
<!--1.该接口是springfox提供的Swagger实例接口-->
<servlet-mapping>
<servlet-name>knife4jDemoMvc</servlet-name>
<url-pattern>/v2/api-docs</url-pattern>
</servlet-mapping>
<!--2.该接口是springfox提供的Swagger分组接口-->
<servlet-mapping>
<servlet-name>knife4jDemoMvc</servlet-name>
<url-pattern>/swagger-resources</url-pattern>
</servlet-mapping>
<!--3.该接口是springfox提供的Swagger配置接口-->
<servlet-mapping>
<servlet-name>knife4jDemoMvc</servlet-name>
<url-pattern>/swagger-resources/configuration/ui</url-pattern>
</servlet-mapping>
5> 启动测试
2. Spring Boot集成knife4j
1> 依赖引用
<dependency>
<groupId>com.github.xiaoymin</groupId>
<artifactId>knife4j-openapi3-jakarta-spring-boot-starter</artifactId>
<version>4.4.0</version>
</dependency>
注意,我这里springBoot的版本为3.3.2
2> 创建配置文件(核心为Swagger)
创建配置文件application.yml
springdoc:
swagger-ui:
path: /swagger-ui.html
tags-sorter: alpha
operations-sorter: alpha
api-docs:
path: /v3/api-docs
group-configs:
- group: '潘大佬'
paths-to-match: '/**'
#生成文档所需的扫包路径,一般为启动类目录
packages-to-scan: com.nianxi.springboot02
#knife4j配置
knife4j:
#是否启用增强设置
enable: true
#开启生产环境屏蔽
production: false
#是否启用登录认证
basic:
enable: true
username: admin
password: 123456
setting:
language: zh_cn
enable-version: true
enable-swagger-models: true
swagger-model-name: 用户模块
3> 配置接口文档简介(Knife4jConfig)
在config包下创建Knife4jConfig.java类
package com.nianxi.springboot02.config;
import io.swagger.v3.oas.models.OpenAPI;
import io.swagger.v3.oas.models.info.Contact;
import io.swagger.v3.oas.models.info.Info;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
@Configuration
public class Knife4jConfig {
@Bean
public OpenAPI springShopOpenApi() {
return new OpenAPI()
// 接口文档标题
.info(new Info().title("潘大佬demo")
// 接口文档简介
.description("这是基于Knife4j OpenApi3的测试接口文档")
// 接口文档版本
.version("1.0版本")
// 开发者联系方式
.contact(new Contact().name("潘大佬")
.email("1013909690@qq.com")));
}
}
4> 配置要显示的内容,即application.yml里面扫描路径的contriller包
在conrtoller包中创建UserController
package com.nianxi.springboot02.controller;
import com.nianxi.springboot02.entity.User;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.Parameter;
import io.swagger.v3.oas.annotations.Parameters;
import io.swagger.v3.oas.annotations.enums.ParameterIn;
import io.swagger.v3.oas.annotations.tags.Tag;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.*;
@RestController
@RequestMapping("body")
@Tag(name = "body参数")
public class UserController {
@Operation(summary = "普通body请求")
@PostMapping("/body")
public ResponseEntity<User> body(@RequestBody User user){
return ResponseEntity.ok(user);
}
@Operation(summary = "普通body请求+Param+Header+Path")
@Parameters({
@Parameter(name = "id",description = "文件id",in = ParameterIn.PATH),
@Parameter(name = "token",description = "请求token",required = true,in = ParameterIn.HEADER),
@Parameter(name = "name",description = "文件名称",required = true,in=ParameterIn.QUERY)
})
@PostMapping("/bodyParamHeaderPath/{id}")
public ResponseEntity<User> bodyParamHeaderPath(@PathVariable("id") String id, @RequestHeader("token") String token, @RequestParam("name")String name, @RequestBody User user){
user.setName(user.getName()+",receiveName:"+name+",token:"+token+",pathID:"+id);
return ResponseEntity.ok(user);
}
}
5> 创建实体类
package com.nianxi.springboot02.entity;
import com.github.xiaoymin.knife4j.annotations.ApiOperationSupport;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.Data;
@Data
public class User {
@Schema(name = "用户名")
private String name;
private String id;
private String age;
private String emall;
}
6> 最终依赖
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>3.3.2</version>
<relativePath/> <!-- lookup parent from repository -->
</parent>
<groupId>com.nianxi</groupId>
<artifactId>SpringBoot-02</artifactId>
<version>0.0.1-SNAPSHOT</version>
<name>SpringBoot-02</name>
<description>SpringBoot-02</description>
<url/>
<licenses>
<license/>
</licenses>
<developers>
<developer/>
</developers>
<scm>
<connection/>
<developerConnection/>
<tag/>
<url/>
</scm>
<properties>
<java.version>17</java.version>
</properties>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web-services</artifactId>
</dependency>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<optional>true</optional>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>com.github.xiaoymin</groupId>
<artifactId>knife4j-openapi3-jakarta-spring-boot-starter</artifactId>
<version>4.4.0</version>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
<configuration>
<excludes>
<exclude>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
</exclude>
</excludes>
</configuration>
</plugin>
</plugins>
</build>
</project>
7> 运行启动类,浏览器搜索localhost:8080/doc.html
三. 注解说明(OpenAPI3规范)
@Tag
用于说明或定义的标签。
部分参数:
name
:名称description
:描述
@Schema
用于描述实体类属性的描述、示例、验证规则等,比如 POJO 类及属性。
部分参数:
name
:名称title
:标题description
:描述example
:示例值required
:是否为必须format
:属性的格式。如@Schema(format = "email")
maxLength
、minLength
:指定字符串属性的最大长度和最小长度maximum
、minimum
:指定数值属性的最大值和最小值pattern
:指定属性的正则表达式模式type
: 数据类型(integer,long,float,double,string,byte,binary,boolean,date,dateTime,password),必须是字符串。如@Schema=(type="integer")
implementation
:具体的实现类,可以是类本身,也可以是父类或实现的接口
@Content
内容注解。
部分参数:
mediaType
:内容的类型。比如:application/jsonschema
:内容的模型定义,使用 @Schema 注解指定模型的相关信息。
@RequestBody(content = @Content(mediaType = "application/json", schema = @Schema(implementation = User.class)))
@PostMapping("/users")
public void createUser(User user) {
// ...
}
@Hidden
某个元素(API 操作、实体类属性等)是否在 API 文档中隐藏。
如,getUserById
方法不会显示在 API 文档中
使用在实体类字段中,实现对敏感信息或不需要公开的元素进行隐藏。如:用户密码字段
@Operation
描述 API 操作的元数据信息。常用于 controller 上
部分参数:
summary
:简短描述description
:更详细的描述hidden
:是否隐藏tags
:标签,用于分组APIoperationId
:操作的唯一标识符,建议使用唯一且具有描述性的名称parameters
:指定相关的请求参数,使用@Parameter
注解来定义参数的详细属性。requestBody
:指定请求的内容,使用@RequestBody
注解來指定请求的类型。responses
:指定操作的返回内容,使用@ApiResponse
注解定义返回值的详细属性。
@Parameter
用于描述 API 操作中的参数
部分参数:
name
: 指定的参数名in
:参数来源,可选query
、header
、path
或cookie
,默认为空,表示忽略ParameterIn.QUERY
请求参数ParameterIn.PATH
路径参数ParameterIn.HEADER
header参数ParameterIn.COOKIE
cookie 参数
description
:参数描述required
:是否必填,默认为 falseschema
:参数的数据类型。如schema = @Schema(type = "string")
@Parameters
包含多个 @Parameter
注解,指定多个参数。
代码参考:
包含了 param1 和 param2 两个参数
@RequestBody
API 请求的注解
description
:请求信息的描述content
:请求的内容required
:是否必须
@ApiResponse
API 的响应信息。
部分参数:
responseCode
:响应的 HTTP 状态码description
:响应信息的描述content
:响应的内容
❤️❤️❤️