Spring Boot3整合Knife4j(4.5.0)
整体概述
Spring Boot 是用于简化 Spring 应用开发的框架,通过自动配置和约定大于配置原则,能让开发者快速搭建和运行 Spring 应用。Knife4j 是基于 Swagger 增强的 API 文档生成工具,可方便展示和调试 API 接口,生成美观易用的 API 文档。以下将详细介绍如何从零开始把 Spring Boot 3.3.0 与 Knife4j 4.5.0 进行整合。
步骤 1:创建 Spring Boot 项目
方式一:使用 Spring Initializr
Spring Initializr 是在线的 Spring Boot 项目生成器,提供图形化界面,便于快速创建项目。
- 打开浏览器,访问 Spring Initializr。
- 在页面做如下配置:
- Project:选
Maven Project
,Maven 是项目管理和构建工具,可管理项目依赖、编译、打包等操作。 - Language:选
Java
,使用 Java 语言开发。 - Spring Boot:选
3.3.0
,即要使用的 Spring Boot 版本。 - Group:通常是公司或组织域名倒序,如
com.example
,用于唯一标识项目所属组织或团队。 - Artifact:是项目名称,如
spring - boot - knife4j - demo
,是项目在 Maven 仓库的唯一标识符。 - Dependencies:点击
Add Dependencies
按钮,搜索并添加Spring Web
依赖,Spring Web
用于开发 Web 应用,包含 Spring MVC 等核心组件。
- Project:选
- 配置完成后,点击
Generate
按钮,浏览器会下载项目压缩包。 - 解压下载的压缩包,用喜欢的集成开发环境(IDE)打开项目。以 IntelliJ IDEA 为例,打开 IDE,选
File
->Open
,再选解压后的项目文件夹。
方式二:使用 IDE 自带的 Spring Initializr
若使用 IntelliJ IDEA,也可通过其自带的 Spring Initializr 创建项目:
- 打开 IntelliJ IDEA,选
File
->New
->Project
。 - 在左侧面板选
Spring Initializr
,按上述步骤 2 配置。 - 点击
Next
,选项目存储位置,再点击Finish
完成项目创建。
步骤 2:添加 Knife4j 依赖
在项目的 pom.xml
文件中添加 Knife4j 依赖。pom.xml
是 Maven 项目配置文件,用于管理项目依赖和构建信息。打开 pom.xml
文件,在 <dependencies>
标签内添加以下代码:
<dependencies>
<!-- Spring Web 依赖,用于开发 Web 应用 -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<!-- Knife4j 依赖,用于生成和展示 API 文档 -->
<dependency>
<groupId>com.github.xiaoymin</groupId>
<artifactId>knife4j-openapi3-jakarta-spring-boot-starter</artifactId>
<version>4.5.0</version>
</dependency>
</dependencies>
添加依赖后,Maven 会自动从中央仓库下载所需库文件。在 IntelliJ IDEA 中,IDE 会自动检测 pom.xml
文件变化,并提示导入依赖,点击 Import Changes
按钮,等待依赖下载完成。
步骤 3: Knife4j 界面自定义配置
package org.example.test1;
import org.springdoc.core.models.GroupedOpenApi;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
@Configuration
public class Knife4jConfig {
@Bean
public GroupedOpenApi api4() {
return GroupedOpenApi.builder()
.group("all")
.displayName("所有接口")
.packagesToScan("org.example.test1")
// 自定义全局响应码
// .addOpenApiCustomizer((this::setCustomStatusCode))
.build();
}
}
步骤 4:创建实体类
实体类用于表示业务数据,使用 Swagger 注解为实体类和其属性添加描述信息,以便在 API 文档中清晰展示。
@Schema 注解用于为实体类添加描述信息,name 为实体类在文档中的名称,description 为详细描述
@Schema 注解为属性添加描述信息,description 为属性描述,example 为示例值
import io.swagger.v3.oas.annotations.media.Schema;
// @Schema 注解用于为实体类添加描述信息,name 为实体类在文档中的名称,description 为详细描述
@Schema(name = "User", description = "用户实体类")
public class User {
// @Schema 注解为属性添加描述信息,description 为属性描述,example 为示例值
@Schema(description = "用户 ID", example = "1")
private Long id;
@Schema(description = "用户名", example = "张三")
private String username;
@Schema(description = "用户邮箱", example = "666@example.com")
private String email;
// 构造函数、Getter 和 Setter 方法
public User() {
}
public User(Long id, String username, String email) {
this.id = id;
this.username = username;
this.email = email;
}
public Long getId() {
return id;
}
public void setId(Long id) {
this.id = id;
}
public String getUsername() {
return username;
}
public void setUsername(String username) {
this.username = username;
}
public String getEmail() {
return email;
}
public void setEmail(String email) {
this.email = email;
}
}
步骤 5:创建 Controller
Controller 负责处理客户端请求并返回响应。使用更多 Swagger 注解描述接口的请求参数、响应结果等信息。
// @Tag 用于对 API 接口进行分组和描述,name 为分组名称,description 为分组详细描述
// @Operation 描述接口的操作信息,summary 为摘要,description 为详细描述
// @ApiResponses 定义接口的响应状态码和对应的响应信息
import io.swagger.v3.oas.annotations.Operation; // 导入Swagger Operation注解,用于描述API操作
import io.swagger.v3.oas.annotations.Parameter; // 导入Swagger Parameter注解,用于描述API参数
import io.swagger.v3.oas.annotations.media.Content; // 导入Swagger Content注解,用于定义API响应内容类型
import io.swagger.v3.oas.annotations.media.Schema; // 导入Swagger Schema注解,用于定义API响应模式
import io.swagger.v3.oas.annotations.responses.ApiResponse; // 导入Swagger ApiResponse注解,用于定义API响应信息
import io.swagger.v3.oas.annotations.responses.ApiResponses; // 导入Swagger ApiResponses注解,用于定义多个API响应信息
import io.swagger.v3.oas.annotations.tags.Tag; // 导入Swagger Tag注解,用于对API进行分组和描述
import org.springframework.web.bind.annotation.*; // 导入Spring MVC注解,用于处理HTTP请求
import java.util.ArrayList; // 导入ArrayList类,用于动态数组操作
import java.util.List; // 导入List接口
// @RestController 是 @Controller 和 @ResponseBody 的组合注解,标识该类是RESTful风格的控制器
@RestController
// @RequestMapping 用于映射请求的URL前缀
@RequestMapping("/api/users")
// @Tag 用于对API接口进行分组和描述,name 为分组名称,description 为分组详细描述
@Tag(name = "用户管理接口", description = "提供用户相关的操作接口")
public class UserController {
private List<User> users = new ArrayList<>(); // 创建一个List集合用于存储用户数据
// @Operation 描述接口的操作信息,summary 为摘要,description 为详细描述
@Operation(summary = "获取所有用户", description = "返回所有用户的列表")
// @ApiResponses 定义接口的响应状态码和对应的响应信息
@ApiResponses(value = {
// @ApiResponse 具体描述某个响应状态码的信息,responseCode 为响应状态码,description 为描述,content 为响应内容
@ApiResponse(responseCode = "200", description = "成功获取用户列表",
content = {@Content(mediaType = "application/json",
// @Schema 指定响应内容的数据结构
schema = @Schema(implementation = User.class))}})
})
@GetMapping
public List<User> getUsers() { // 定义一个GET请求处理方法,返回用户列表
return users; // 返回用户列表
}
@Operation(summary = "根据 ID 获取用户", description = "根据用户 ID 获取单个用户信息")
@ApiResponses(value = {
@ApiResponse(responseCode = "200", description = "成功获取用户信息",
content = {@Content(mediaType = "application/json",
schema = @Schema(implementation = User.class))}),
@ApiResponse(responseCode = "404", description = "未找到该用户", content = @Content)})
// @Parameter 描述接口的请求参数,description 为参数描述,example 为示例值
@GetMapping("/{id}")
public User getUserById(@Parameter(description = "用户 ID", example = "1") @PathVariable Long id) { // 定义一个GET请求处理方法,根据ID获取用户信息
return users.stream() // 将用户列表转换为流
.filter(user -> user.getId().equals(id)) // 过滤出ID匹配的用户
.findFirst() // 查找第一个匹配的用户
.orElse(null); // 如果没有找到,返回null
}
@Operation(summary = "创建用户", description = "创建一个新的用户")
@ApiResponses(value = {
@ApiResponse(responseCode = "201", description = "用户创建成功",
content = {@Content(mediaType = "application/json",
schema = @Schema(implementation = User.class))}})
@PostMapping
public User createUser(@Parameter(description = "用户信息", required = true) @RequestBody User user) { // 定义一个POST请求处理方法,创建新用户
users.add(user); // 将新用户添加到列表
return user; // 返回创建的用户
}
@Operation(summary = "获取所有用户2", description = "返回所有用户的列表")
@ApiResponses(value = {
@ApiResponse(responseCode = "200", description = "成功获取用户列表",
content = {@Content(mediaType = "application/json",
schema = @Schema(implementation = User.class))}})
@GetMapping
public List<User> getUsers2(@Parameter(name = "X-Token", description = "自定义请求头 token", in = ParameterIn.HEADER) @RequestHeader(required = false) String token) { // 定义一个GET请求处理方法,返回用户列表,支持自定义请求头参数
return users; // 返回用户列表
}
}
步骤 6:启动 Spring Boot 应用
在 IDE 中找到项目的启动类(通常是包含 main
方法且带有 @SpringBootApplication
注解的类),右键点击并选择 Run
启动 Spring Boot 应用。启动成功后,控制台会输出启动信息,表明应用已在默认端口(通常是 8080)启动。
步骤 7:访问 Knife4j 文档页面
打开浏览器,访问以下 URL 查看 Knife4j 生成的 API 文档:http://localhost:8080/doc.html
在Springboot的yml文件中配置Knife4j
# Knife4j配置
# springdoc-openapi配置
springdoc:
# get请求多参数时不需要添加额外的@ParameterObject和@Parameter注解
default-flat-param-object: true
# 启用swaggerUI
swagger-ui:
#自定义swagger前端请求路径,输入http:127.0.0.1:8080/swagger-ui.html会自动重定向到swagger页面
path: /swagger-ui.html
enabled: true
# tags-sorter: alpha # 标签的排序方式 alpha:按照子母顺序排序(@ApiSupport注解排序不生效,因此需要设置)
# operations-sorter: alpha # 接口的排序方式 alpha:按照子母顺序排序(@ApiOperationSupport注解排序生效,因此这里不作设置)
operations-sorter: order # 设置规则为order,该规则会使用Knife4j的增强排序扩展规则`x-order`
# 启用文档,默认开启
api-docs:
path: /v3/api-docs #swagger后端请求地址
enabled: true
# knife4j相关配置 可以不用改
knife4j:
enable: true #开启knife4j,无需添加@EnableKnife4j注解
setting:
language: ZH_CN # 中文:ZH_CN 英文:EN
enable-swagger-models: true
enable-dynamic-parameter: false
footer-custom-content: "<strong>Copyright ©️ 2024 Keyidea. All Rights Reversed</strong>"
enable-footer-custom: true
enable-footer: true
enable-document-manage: true
documents: #文档补充说明
- name: MarkDown语法说明
locations: classpath:static/markdown/grammar/*
group: 01-系统接口 # 此处分组必须使用在Knife4jConfig已存在的分组名group,当存在displayName时,使用displayName名称
- name: 补充文档
locations: classpath:static/markdown/others/*
group: 01-系统接口 # 此处分组必须使用在Knife4jConfig已存在的分组名group,当存在displayName时,使用displayName名称