Spring Boot 实战:用Knife4j 自动生成接口文档,告别手写时代
大家好呀!在上一篇文章中,我们已经通过全局异常处理和统一返回格式,让 Spring Boot 接口达到了企业级健壮性标准。但在前后端协作中,还有一个关键痛点亟待解决 ——接口文档维护。
后端同学每次调整接口参数、返回格式,都要手动更新文档;前端同学则需反复确认接口地址、参数类型、响应结构,沟通成本极高。今天这篇就针对Spring Boot 3.5.7 版本,教大家集成适配的 Knife4j 版本,实现接口文档自动生成、实时同步、在线调试,彻底摆脱手写文档的繁琐,让前后端协作效率翻倍!
全程分 5 步走,每一步都针对 Spring Boot 3.5.7 的特性做了适配,提供可直接复制的代码和操作说明,零基础也能轻松上手~
一、先搞懂:为什么选 Knife4j?
Spring Boot 3.5.7 作为 3.x 系列的较新版本,在依赖管理、Jakarta EE 规范适配上有明确要求,传统 Swagger 工具(如 Springfox)已停止维护,无法兼容该版本,而 Knife4j 针对 3.x 系列做了持续优化,优势显著:
1. Knife4j 的核心优势
- 增强型 UI 体验:提供比官方 Swagger 更清晰的界面,支持接口分组、参数说明、响应结构展示,符合国内开发者使用习惯;
- 轻量化集成:仅需引入一个 starter 依赖 + 简单配置,无需额外整合复杂组件,快速落地。
简单来说,在 Spring Boot 3.5.7 中集成 Knife4j,是实现接口文档自动化的最优选择,既能保障兼容性,又能提升协作效率。
二、准备工作
我们直接在 Spring Boot 3.5.7 版本的first-springboot-project项目上集成 Knife4j,确保:
- 项目
pom.xml中 Spring Boot 版本已指定为 3.5.7:
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>3.5.7</version>
<relativePath/> <!-- lookup parent from repository -->
</parent>
- 项目已实现统一返回格式(Result 类)和全局异常处理,接口能正常返回 JSON 数据;
- 已引入 Lombok 依赖(简化实体类代码,可选但推荐)。
三、第一步:添加 Knife4j 依赖(适配 Spring Boot 3.5.7)
1. 打开 pom.xml 文件
在左侧项目结构中,找到src/main/resources下的pom.xml,双击打开。
2. 添加依赖代码
在<dependencies>标签内粘贴以下依赖(Knife4j 4.5.0 为适配 3.5.7 的稳定版本):
<dependency>
<groupId>com.github.xiaoymin</groupId>
<artifactId>knife4j-openapi3-jakarta-spring-boot-starter</artifactId>
<version>4.5.0</version>
</dependency>
刷新依赖:添加后点击 IDEA 右上角的 “Load Maven Changes” 图标,等待 Maven 下载依赖(右下角进度条走完无红色报错即可)。
四、第二步:添加 Knife4j 配置项
1. yaml中添加Knife4j配置项
# springdoc-openapi项目配置
springdoc:
swagger-ui:
path: /swagger-ui.html
tags-sorter: alpha
operations-sorter: alpha
api-docs:
path: /v3/api-docs
group-configs:
- group: 'default'
paths-to-match: '/**'
packages-to-scan: com.example.firstspringbootproject
# knife4j的增强配置,不需要增强可以不配
knife4j:
enable: true
setting:
language: zh_cn
五:第三步:版本兼容性处理
knife4j 4.5.0 仅支持springboot 3.4以下版本,springboot 3.5.7版本需要在全局异常处理类加一个@Hidden注解来解决。
package com.example.firstspringbootproject.common;
import io.swagger.v3.oas.annotations.Hidden;
import lombok.extern.slf4j.Slf4j;
import org.springframework.http.converter.HttpMessageNotReadableException;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.RestControllerAdvice;
// @RestControllerAdvice:全局异常处理注解,作用于所有@RestController类
// @Slf4j:Lombok注解,自动生成日志对象(用来打印异常信息,方便调试)
@Hidden
@RestControllerAdvice
@Slf4j
public class GlobalExceptionHandler {
// 1. 捕获所有RuntimeException(运行时异常,比如空指针、数据库操作异常)
@ExceptionHandler(RuntimeException.class)
public Result<Void> handleRuntimeException(RuntimeException e) {
// 打印异常信息到控制台(方便开发时排查问题)
log.error("运行时异常:", e);
// 返回友好提示(不暴露具体异常信息给前端)
return Result.error(500, "服务器内部错误,请联系管理员");
}
// 2. 捕获JSON格式错误异常(比如前端传的JSON格式不对)
@ExceptionHandler(HttpMessageNotReadableException.class)
public Result<Void> handleJsonParseException(HttpMessageNotReadableException e) {
log.error("JSON格式错误:", e);
return Result.error(400, "请求参数格式错误,请检查JSON格式");
}
// 3. 捕获自定义异常(后面会讲,先预留)
@ExceptionHandler(BusinessException.class)
public Result<Void> handleBusinessException(BusinessException e) {
// 自定义异常的状态码和提示信息,直接返回
return Result.error(e.getCode(), e.getMsg());
}
// 4. 捕获所有其他异常(兜底,防止有遗漏的异常)
@ExceptionHandler(Exception.class)
public Result<Void> handleException(Exception e) {
log.error("未知异常:", e);
return Result.error(500, "服务器内部错误,请联系管理员");
}
}
六、第四步:给接口和实体类加 “文档注解”
1. 给 Controller 接口加注解
打开DbController类,使用@Tag、@Operation、@Parameter等注解描述接口功能和参数:
package com.example.firstspringbootproject.controller;
import com.example.firstspringbootproject.common.Result;
import com.example.firstspringbootproject.entity.Product;
import com.example.firstspringbootproject.entity.User;
import com.example.firstspringbootproject.service.ProductService;
import com.example.firstspringbootproject.service.UserService;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.Parameter;
import io.swagger.v3.oas.annotations.tags.Tag;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;
import java.util.List;
// @Tag:描述Controller分组(替代旧@Api),显示在文档左侧菜单
@Tag(name = "用户管理与商品查询接口", description = "包含用户CRUD、商品模糊查询等核心业务接口,基于Spring Boot 3.5.7开发")
@RestController
@RequestMapping("/api")
public class DbController {
@Autowired
private UserService userService;
@Autowired
private ProductService productService;
// @Operation:描述接口功能(替代旧@ApiOperation)
// @Parameter:描述单个参数(替代旧@ApiImplicitParam)
@Operation(summary = "根据ID查询用户", description = "传入用户ID(如1),返回用户姓名、年龄、手机号等完整信息,查询不到返回404")
@GetMapping("/user/{userId}")
public Result<User> getUser(
@Parameter(description = "用户ID(必填)", required = true, example = "1")
@PathVariable Integer userId) {
User user = userService.getUserById(userId);
return user != null ? Result.success(user) : Result.error(404, "用户不存在");
}
@Operation(summary = "新增用户", description = "传入用户姓名、年龄、手机号(手机号唯一),ID由系统自动生成,新增成功返回200")
@PostMapping("/user")
public Result<Void> addUser(
@Parameter(description = "用户信息(姓名必填,手机号唯一)", required = true)
@RequestBody User user) {
boolean success = userService.addUser(user);
return success ? Result.success() : Result.error(500, "新增用户失败");
}
@Operation(summary = "查询所有用户", description = "返回系统中所有已注册用户列表,包含每个用户的完整字段信息")
@GetMapping("/user/all")
public Result<List<User>> getAllUsers() {
return Result.success(userService.getAllUsers());
}
@Operation(summary = "模糊搜索商品", description = "传入商品名称关键词(如“手机”),返回所有名称包含该关键词的商品,支持空关键词(返回所有商品)")
@GetMapping("/product/search")
public Result<List<Product>> searchProduct(
@Parameter(description = "商品名称关键词(可选,默认空)", example = "手机")
@RequestParam(required = false, defaultValue = "") String name) {
return Result.success(productService.searchProductByName(name));
}
@Operation(summary = "根据ID查询商品", description = "传入商品ID(如1),返回商品名称、价格、库存等完整信息,查询不到返回404")
@GetMapping("/product/{productId}")
public Result<Product> getProduct(
@Parameter(description = "商品ID(必填)", required = true, example = "1")
@PathVariable Integer productId) {
Product product = productService.getProductById(productId);
return product != null ? Result.success(product) : Result.error(404, "商品不存在");
}
}
2. 给实体类加注解
给User和Product实体类添加@Schema注解,说明字段含义、是否必填及示例值,让文档中响应结构更清晰:
(1)User 实体类
package com.example.firstspringbootproject.entity;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.Data;
// @Schema:描述实体类(替代旧@ApiModel)
@Schema(name = "User", description = "用户信息实体类,存储用户的基本属性")
@Data
@AllArgsConstructor
public class User {
// @Schema:描述字段(替代旧@ApiModelProperty)
@Schema(description = "用户ID(自增主键,创建时无需传入)", example = "1")
private Integer id;
@Schema(description = "用户名(必填,长度1-50)", required = true, example = "小明")
private String name;
@Schema(description = "用户年龄(可选,范围0-150)", example = "20")
private Integer age;
@Schema(description = "用户手机号(可选,唯一,格式11位)", example = "13800138000")
private String phone;
}
(2)Product 实体类
package com.example.firstspringbootproject.entity;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.Data;
@Schema(name = "Product", description = "商品信息实体类,存储商品的名称、价格、库存等属性")
@Data
public class Product {
@Schema(description = "商品ID(自增主键,创建时无需传入)", example = "1")
private Integer productId;
@Schema(description = "商品名称(必填,长度1-100)", required = true, example = "华为手机")
private String productName;
@Schema(description = "商品价格(必填,大于0)", required = true, example = "3999.0")
private Double price;
@Schema(description = "商品库存(必填,大于等于0)", required = true, example = "100")
private Integer stock;
}
3. 注解总结(新版)
| 新版 Swagger 3.x 注解(当前使用) | 作用范围 | 说明 |
|---|---|---|
@Tag(name = "xxx") | Controller 类 | 对 Controller 进行分组,标题显示在文档左侧菜单 |
@Operation(...) | 接口方法 | 描述接口功能,summary为简要说明,description为详细说明 |
@Parameter(...) | 接口参数 | 描述单个参数的含义、是否必填、示例值,支持路径、查询、请求体参数 |
@Schema(...) | 实体类 | 描述实体类的作用,方便文档中展示请求 / 响应结构 |
@Schema(...) | 实体类字段 | 描述字段的含义、示例值,支持标记必填项 |
七、第五步:启动项目,查看并调试接口文档
所有配置和注解完成后,启动 Spring Boot 3.5.7 项目,即可通过 Knife4j 的 UI 界面查看、调试接口文档:
1. 启动项目
找到FirstSpringbootProjectApplication启动类(确保类上有@SpringBootApplication注解),点击绿色三角运行,控制台显示以下日志且无红色报错,说明启动成功:
Started FirstSpringbootProjectApplication in 2.87 seconds (process running for 3.24)
2. 访问 Knife4j 文档页面
打开浏览器,输入地址:http://localhost:8080/doc.html(Knife4j 在 3.5.7 中的默认访问路径不变),进入文档首页:
- 首页显示
springBoot357OpenAPI()中配置的标题、描述、版本及联系人信息; - 左侧菜单显示
@Tag定义的接口分组(如 “用户管理与商品查询接口”); - 文档管理支持 “文档下载”“全局参数配置” 等功能按钮。
3. 查看接口详情
点击左侧接口分组,展开所有接口,以 “根据 ID 查询用户” 为例:
- 接口详情页显示
@Operation描述的功能说明; - “请求参数” 区域显示
@Parameter定义的用户 ID 参数(必填、示例值 1); - “响应示例” 区域自动展示统一返回格式(Result 结构),并标注
@Schema定义的 User 字段含义。
4. 在线调试接口(无需第三方工具)
在 Knife4j 中可直接调试接口,无需打开 Postman 或 ApiFox,以 “新增用户” 为例:
- 找到 “新增用户” 接口,点击右侧 “调试” 按钮;
- 在 “请求体” 区域,自动生成 User 实体类的 JSON 模板,输入测试数据:
{
"name": "小李",
"age": 22,
"phone": "13700137000"
}
- 点击 “发送” 按钮,下方 “响应结果” 区域显示:
{
"code": 200,
"msg": "success",
"data": null
}
- 验证数据库:在 DataGrip 中打开
user表,能看到新增的 “小李” 记录(ID 自增),说明调试成功。
再以 “模糊搜索商品” 为例:
- 输入 name=“手机”,点击发送,响应结果返回 2 条数据(华为手机、OPPO 手机),与数据库数据一致。
5. 导出离线文档(适配前端需求)
若前端同学需要离线文档,Knife4j 支持多种格式导出(适配 Spring Boot 3.5.7):
- 点击文档管理下 “离线文档” 按钮;
- 选择导出格式(推荐 Markdown,兼容性最好,支持大多数文档平台);
- 点击 “下载”,获取的文档包含接口地址、参数说明、响应格式、示例值等所有信息,可直接分享给前端团队。
七、总结:Spring Boot 3.5.7 接口文档自动化落地
今天我们完成了 Knife4j 在 Spring Boot 3.5.7 中的集成,重点掌握了:
- 简洁配置:基于
OpenAPI规范配置文档信息,无需旧版启用注解,减少配置冗余; - 注解升级:使用 Swagger 3.x 注解描述接口和实体类,让文档更清晰、专业;
- 高效协作:在线调试 + 离线导出,前端无需反复询问接口细节,协作效率提升 50% 以上。
现在,你的 Spring Boot 3.5.7 项目已经具备企业级的接口文档能力 —— 后端改接口后文档自动同步,前端看文档就能调试,彻底告别 “文档落后于代码” 的问题!
下一篇文章,我会教大家 “Spring Boot 3.5.7 接口权限控制”(基于 Spring Security 6.3),实现接口的登录验证、角色授权,保障系统安全!
👉 关注+私信“Web基础源码”,获取完整工程!有问题评论区见~