API 接口文档自动化 Knife4j 集成实践
API 接口文档自动化 Knife4j 集成实践
引言
在企业级项目开发中,API 接口文档是前后端协作的桥梁。传统的手工编写文档方式存在维护成本高、容易与代码不同步等问题。Knife4j 作为 Swagger 的增强方案,通过注解自动生成接口文档,支持在线调试,大幅提升了开发效率和协作体验。
本文将介绍 Knife4j 在 Spring Boot 3 项目中的集成配置、注解规范、接口分组、在线调试和文档美化等最佳实践。
核心内容
一、Knife4j 与 SpringDoc 集成架构
graph TD
A[Spring Boot 3应用] --> B[SpringDoc OpenAPI]
B --> C[Swagger注解扫描]
C --> D[OpenAPI规范JSON]
D --> E[Knife4j增强UI]
E --> F[开发者浏览器]
G[Controller注解] --> C
H[DTO注解] --> C
style E fill:#c8e6c9
style B fill:#e1f5fe
Spring Boot 3 不再支持 Springfox(Swagger 2),需要使用 SpringDoc(OpenAPI 3)+ Knife4j 的组合方案。
二、集成配置
1. Maven 依赖
<!-- SpringDoc OpenAPI -->
<dependency>
<groupId>org.springdoc</groupId>
<artifactId>springdoc-openapi-starter-webmvc-ui</artifactId>
<version>2.3.0</version>
</dependency>
<!-- Knife4j 增强UI -->
<dependency>
<groupId>com.github.xiaoymin</groupId>
<artifactId>knife4j-openapi3-jakarta-spring-boot-starter</artifactId>
<version>4.4.0</version>
</dependency>
注意:Spring Boot 3 使用 Jakarta EE 规范,必须选择
jakarta版本的 Knife4j。
2. 配置文件
# application.yml
springdoc:
api-docs:
enabled: true
path: /v3/api-docs
swagger-ui:
path: /swagger-ui.html
tags-sorter: alpha
operations-sorter: alpha
group-configs:
- group: '系统管理'
packages-to-scan: com.example.system.controller
- group: '代码生成'
packages-to-scan: com.example.codegen.controller
- group: 'AI对话'
packages-to-scan: com.example.ai.controller
# Knife4j增强配置
knife4j:
enable: true
setting:
language: zh_cn
enable-version: true
enable-swagger-models: true
swagger-model-name: 数据模型
openapi:
title: 企业级低代码平台API文档
description: 平台所有接口文档及在线调试
version: 1.0.0
contact:
name: 开发团队
email: dev@example.com
3. 配置类
@Configuration
public class Knife4jConfig {
@Bean
public OpenAPI customOpenAPI() {
return new OpenAPI()
.info(new Info()
.title("企业级低代码平台API文档")
.description("基于Spring Boot 3 + Java 21的企业级低代码开发平台接口文档")
.version("v1.0.0")
.contact(new Contact()
.name("开发团队")
.email("dev@example.com")))
.externalDocs(new ExternalDocumentation()
.description("项目Wiki")
.url("https://wiki.example.com"));
}
}
4. 安全认证配置
@Configuration
public class SecuritySchemaConfig {
/**
* 配置全局安全方案
* 使所有接口支持Token认证
*/
@Bean
public OpenAPI securityOpenAPI() {
return new OpenAPI()
.schemaRequirement("Bearer", new SecurityScheme()
.type(SecurityScheme.Type.HTTP)
.scheme("bearer")
.bearerFormat("JWT")
.in(SecurityScheme.In.HEADER)
.name("Authorization"))
.addSecurityItem(new SecurityRequirement().addList("Bearer"));
}
}
三、注解规范
1. Controller 注解
@RestController
@RequestMapping("/api/system/user")
@Tag(name = "用户管理", description = "用户CRUD、角色分配、状态管理")
public class UserController {
@Operation(
summary = "分页查询用户列表",
description = "支持按用户名、状态、创建时间等条件筛选"
)
@Parameters({
@Parameter(name = "page", description = "页码", example = "1"),
@Parameter(name = "size", description = "每页条数", example = "10"),
@Parameter(name = "username", description = "用户名(模糊查询)"),
@Parameter(name = "status", description = "状态:0-禁用 1-启用")
})
@ApiResponse(responseCode = "200", description = "查询成功")
@GetMapping("/page")
public Result<PageResult<UserVO>> pageQuery(
@RequestParam(defaultValue = "1") Integer page,
@RequestParam(defaultValue = "10") Integer size,
@RequestParam(required = false) String username,
@RequestParam(required = false) Integer status) {
// 业务逻辑
return Result.success(userService.pageQuery(page, size, username, status));
}
@Operation(summary = "创建用户", description = "创建新用户并分配角色")
@io.swagger.v3.oas.annotations.responses.ApiResponses({
@ApiResponse(responseCode = "200", description = "创建成功"),
@ApiResponse(responseCode = "400", description = "参数校验失败"),
@ApiResponse(responseCode = "409", description = "用户名已存在")
})
@PostMapping
public Result<Void> create(@RequestBody @Valid UserCreateDTO dto) {
userService.createUser(dto);
return Result.success();
}
@Operation(summary = "删除用户", description = "逻辑删除用户")
@Parameter(name = "id", description = "用户ID", required = true, example = "1")
@DeleteMapping("/{id}")
public Result<Void> delete(@PathVariable Long id) {
userService.deleteUser(id);
return Result.success();
}
}
2. DTO 注解
@Schema(description = "创建用户请求")
public record UserCreateDTO(
@Schema(description = "用户名", example = "zhangsan", requiredMode = Schema.RequiredMode.REQUIRED)
@NotBlank(message = "用户名不能为空")
@Size(min = 2, max = 20, message = "用户名长度2-20位")
String username,
@Schema(description = "密码", example = "Admin@123", requiredMode = Schema.RequiredMode.REQUIRED)
@NotBlank(message = "密码不能为空")
@Pattern(regexp = "^(?=.*[a-z])(?=.*[A-Z])(?=.*\d).{8,20}$",
message = "密码需8-20位,包含大小写字母和数字")
String password,
@Schema(description = "邮箱", example = "zhangsan@example.com")
@Email(message = "邮箱格式不正确")
String email,
@Schema(description = "角色ID列表", example = "[1, 2]", requiredMode = Schema.RequiredMode.REQUIRED)
@NotEmpty(message = "至少分配一个角色")
List<Long> roleIds,
@Schema(description = "状态:0-禁用 1-启用", example = "1")
Integer status
) {}
3. VO 注解
@Schema(description = "用户信息响应")
public record UserVO(
@Schema(description = "用户ID", example = "1")
Long id,
@Schema(description = "用户名", example = "zhangsan")
String username,
@Schema(description = "邮箱", example = "zhangsan@example.com")
String email,
@Schema(description = "状态:0-禁用 1-启用", example = "1")
Integer status,
@Schema(description = "角色列表")
List<RoleVO> roles,
@Schema(description = "创建时间", example = "2024-01-01 12:00:00")
LocalDateTime createTime
) {}
四、接口分组
企业项目接口众多,合理的分组能让文档结构清晰。
graph TD
A[API文档] --> B[系统管理]
A --> C[代码生成]
A --> D[AI对话]
A --> E[文件管理]
B --> B1[用户管理]
B --> B2[角色管理]
B --> B3[菜单管理]
B --> B4[字典管理]
C --> C1[模板管理]
C --> C2[代码生成]
C --> C3[代码预览]
D --> D1[对话管理]
D --> D2[知识库管理]
D --> D3[模型配置]
E --> E1[文件上传]
E --> E2[文件下载]
E --> E3[文件管理]
分组配置
@Configuration
public class SwaggerGroupConfig {
/** 系统管理分组 */
@Bean
public GroupedOpenApi systemApi() {
return GroupedOpenApi.builder()
.group("系统管理")
.packagesToScan("com.example.system.controller")
.pathsToMatch("/api/system/**")
.addOpenApiMethodFilter(method ->
method.getDeclaringClass().getPackageName()
.startsWith("com.example.system"))
.build();
}
/** 代码生成分组 */
@Bean
public GroupedOpenApi codegenApi() {
return GroupedOpenApi.builder()
.group("代码生成")
.packagesToScan("com.example.codegen.controller")
.pathsToMatch("/api/codegen/**")
.build();
}
/** AI对话分组 */
@Bean
public GroupedOpenApi aiApi() {
return GroupedOpenApi.builder()
.group("AI对话")
.packagesToScan("com.example.ai.controller")
.pathsToMatch("/api/ai/**")
.build();
}
}
五、在线调试
Knife4j 提供了比原生 Swagger UI 更强大的在线调试功能:
sequenceDiagram
participant 开发者
participant Knife4jUI
participant 后端服务
开发者->>Knife4jUI: 选择接口
开发者->>Knife4jUI: 填写参数
开发者->>Knife4jUI: 点击调试
Knife4jUI->>后端服务: 发送请求(携带Token)
后端服务-->>Knife4jUI: 返回响应
Knife4jUI-->>开发者: 展示响应结果
Note over Knife4jUI,后端服务: 支持全局Token配置<br/>支持请求缓存<br/>支持响应格式化
全局参数配置
@Configuration
public class GlobalParameterConfig {
@Bean
public GroupedOpenApi globalParamApi() {
return GroupedOpenApi.builder()
.group("全部接口")
.packagesToScan("com.example")
.addGlobalHeaderParameter("Authorization",
"认证Token", "Bearer {token}")
.addGlobalHeaderParameter("X-Tenant-Id",
"租户ID", "1")
.build();
}
}
六、文档美化
自定义文档主题
knife4j:
enable: true
setting:
language: zh_cn
# 启用个性化设置
enable-footer-custom: true
footer-custom-content: "Copyright © 2024 企业级低代码平台"
# 文档模型配置
enable-swagger-models: true
swagger-model-name: 数据模型
# 版本信息
enable-version: true
# 缓存配置
enable-cache-open-api: false
# 生产环境屏蔽
production: false
生产环境保护
@Configuration
@Profile({"dev", "test"})
public class Knife4jConfig {
// 只在开发和测试环境启用文档
}
# application-prod.yml
springdoc:
api-docs:
enabled: false
swagger-ui:
enabled: false
knife4j:
production: true # 生产环境关闭文档
七、注解速查表
| 注解 | 作用位置 | 说明 |
|---|---|---|
@Tag |
Controller类 | 接口分组名称和描述 |
@Operation |
方法 | 接口摘要和详细描述 |
@Parameter |
方法参数 | 参数描述、示例、是否必填 |
@Parameters |
方法 | 多参数描述 |
@Schema |
DTO/VO字段 | 字段描述、示例、必填 |
@ApiResponse |
方法 | 响应码描述 |
@Hidden |
类/方法/字段 | 隐藏接口或字段 |
结论与建议
最佳实践建议
-
注解与校验结合:将
@Schema注解与@NotBlank、@Size等校验注解配合使用,文档自动展示校验规则。 -
接口分组清晰:按业务域分组,每组不超过20个接口,避免单个分组过于庞大。
-
生产环境保护:生产环境必须关闭文档接口,防止敏感信息泄露。
-
版本管理:API版本变更时及时更新文档描述,保持文档与代码同步。
-
示例数据完整:每个参数都应提供有意义的
example,方便前端开发者理解。 -
统一响应格式:使用全局
Result<T>封装,在文档中统一描述响应结构。