Spring Boot 3 接口文档最佳实践:SpringDoc + Knife4j —— Spring AI 实战企业级问卷系统之06
Spring AI 实战企业级问卷系统系列
06 – Spring Boot 3.x 接口文档最佳实践:SpringDoc + Knife4j
大家好,我是优雅哥!
在上一篇文章中,咱们实现了统一异常处理与全局响应封装,规范了 API 接口的响应格式。本文咱们 集成 SpringDoc 和 Knife4j,实现接口文档的自动生成。
本系列文章对应 GitHub 地址:
https://github.com/HeroCloudy/agarwood-voc-springboot
现在定义接口的方式已经有很多了,除了本文使用的 Spring Doc 和 Knife4j,还有 Apifox、Postman 等,各自有各自的侧重和优势,本文不做比较。而 Apifox 等属于软件使用的范畴,没必要在此啰嗦。
1 SpringDoc 与 Knife4j 介绍
1.1 SpringDoc
SpringDoc 是一个用于生成 OpenAPI 3 规范文档的库,它通过扫描 Spring Boot 项目中的注解,自动生成 API 文档。
1)支持 OpenAPI 3 规范
2)与 Spring Boot 深度集成
3)零配置即可使用
4)支持多种注解描述接口信息
1.2 Knife4j
Knife4j 是一个基于 Swagger 的增强 UI 实现,它在 Swagger 的基础上提供了更加美观的界面和更丰富的功能。
1)美观的 UI 界面
2)支持接口分组、搜索
3)支持在线调试
4)支持文档导出(Markdown、HTML、PDF 等)
5)支持接口权限控制
在 Spring Boot 3.x 中,Springfox Swagger 已经不再维护,而 SpringDoc 是官方推荐的替代方案。配合 Knife4j 的增强 UI,可以提供更好的使用体验。
2 搭建 agarwood-components-doc 模块
由于 API 文档功能是通用功能,咱们将其封装到 agarwood-components-doc 模块中,供所有服务复用。
2.1 创建模块
在 agarwood-components 模块下创建子模块 agarwood-components-doc
创建步骤:
agarwood-components 模块New -> ModuleMaven,点击 NextName:
agarwood-components-docParent:
agarwood-components创建该模块完成后,记得在根目录 pom.xml 的 <dependencyManagement> 中添加:
<dependencyManagement>
<dependencies>
...
<dependency>
<groupId>com.agarwood</groupId>
<artifactId>agarwood-components-doc</artifactId>
<version>${agarwood.version}</version>
</dependency>
</dependencies>
</dependencyManagement>
此时 agarwood-components 模块便有两个子模块了:
– agarwood-components-mybatis
– agarwood-components-doc
2.2 添加依赖
在 agarwood-components-doc 的 pom.xml 中添加依赖:
<?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 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>com.agarwood</groupId>
<artifactId>agarwood-components</artifactId>
<version>1.0-SNAPSHOT</version>
</parent>
<artifactId>agarwood-components-doc</artifactId>
<name>agarwood-components-doc</name>
<description>agarwood 文档组件</description>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-autoconfigure</artifactId>
</dependency>
<dependency>
<groupId>org.springdoc</groupId>
<artifactId>springdoc-openapi-starter-webmvc-ui</artifactId>
</dependency>
<dependency>
<groupId>com.github.xiaoymin</groupId>
<artifactId>knife4j-openapi3-jakarta-spring-boot-starter</artifactId>
</dependency>
</dependencies>
</project>
2.3 配置文档属性
类似之前封装 MyBatis Plus,本模块也创建类 DocProperties.java 来配置文档信息:
package com.agarwood.components.doc;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.EqualsAndHashCode;
import lombok.NoArgsConstructor;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.context.annotation.Configuration;
@NoArgsConstructor
@AllArgsConstructor
@Data
@ConfigurationProperties(prefix = "agarwood.doc")
@Configuration
public class DocProperties {
private Info info = new Info();
private ExternalDocumentation externalDocs = new ExternalDocumentation();
/**
* 配置文档基本信息
*/
@EqualsAndHashCode(callSuper = true)
@Data
public static class Info extends io.swagger.v3.oas.models.info.Info {
private License license = new License();
}
/**
* 配置许可证信息
*/
@EqualsAndHashCode(callSuper = true)
@Data
public static class License extends io.swagger.v3.oas.models.info.License {
}
/**
* 配置外部文档链接
*/
@EqualsAndHashCode(callSuper = true)
@Data
public static class ExternalDocumentation extends io.swagger.v3.oas.models.ExternalDocumentation {
}
}
2.4 配置 SpringDoc
创建配置类 SpringDocConfig.java:
package com.agarwood.components.doc;
import io.swagger.v3.oas.models.OpenAPI;
import lombok.RequiredArgsConstructor;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
@RequiredArgsConstructor
@Configuration
public class SpringDocConfig {
private final DocProperties properties;
@Bean
public OpenAPI springShopOpenAPI() {
return new OpenAPI()
.info(properties.getInfo())
.externalDocs(properties.getExternalDocs());
}
}
3 在业务服务中使用
3.1 添加依赖
在 agarwood-voc-service 的 pom.xml 中添加依赖:
<dependencies>
...
<dependency>
<groupId>com.agarwood</groupId>
<artifactId>agarwood-components-doc</artifactId>
</dependency>
</dependencies>
3.2 配置文档信息
在 agarwood-voc-service 的 application.yml 中添加文档配置:
springdoc:
swagger-ui:
path: /swagger-ui.html
enabled: true
api-docs:
path: /v3/api-docs
enabled: true
# 如果不需要分组,可以不配置下列信息
group-configs:
- group: 全部接口
paths-to-match:
- /**
- group: Foo管理
paths-to-match:
- /foo/**
- group: 问卷管理
paths-to-match:
- /voc/**
agarwood:
doc:
info:
title: Agarwood VOC 接口文档
description: Agarwood VOC 智能问卷系统接口文档,包含问卷管理、问卷填写、数据统计等功能
version: v1.0.0
license:
name: Apache 2.0
url: https://www.apache.org/licenses/LICENSE-2.0
external-docs:
description: 项目文档
url: https://github.com/HeroCloudy/agarwood-voc-springboot
3.3 使用注解描述接口
SpringDoc 通过扫描注解自动生成接口文档,常用的注解有:
|
|
|
|
|---|---|---|
@Tag |
|
|
@Operation |
|
|
@Parameter |
|
|
@Schema |
|
|
修改 FooController:
package com.agarwood.voc.controller;
// ... import
// ...
@Tag(name = "Foo管理", description = "Foo 增删改查接口")
public class FooController {
// ...
@GetMapping("/list")
@Operation(summary = "查询所有", description = "查询所有 Foo 数据")
public Result<List<Foo>> list() {
return Result.ok(fooService.list());
}
@PostMapping("/save")
@Operation(summary = "保存", description = "保存 Foo 数据")
public Result<Void> save(@RequestBody Foo foo) {
// ...
}
@PutMapping("/update")
@Operation(summary = "更新", description = "更新 Foo 数据")
public Result<Void> update(@RequestBody Foo foo) {
// ...
}
@DeleteMapping("/delete/{id}")
@Operation(summary = "删除", description = "根据 ID 删除 Foo 数据")
public Result<Void> delete(@Parameter(description = "Foo ID") @PathVariable String id) {
// ...
}
@GetMapping("/get/{id}")
@Operation(summary = "查询详情", description = "根据 ID 查询 Foo 详情")
public Result<Foo> get(@Parameter(description = "Foo ID") @PathVariable String id) {
// ...
}
}
修改 Foo 实体类:
package com.agarwood.voc.entity;
// ... import
// ...
@Schema(description = "Foo 实体类")
public class Foo extends BaseEntity {
@Schema(description = "编码")
@NotBlank(message = "编码不能为空")
private String code;
@Schema(description = "名称")
@NotBlank(message = "名称不能为空")
private String name;
}
4 测试接口文档
启动 agarwood-voc-service 应用,打开浏览器,访问以下地址:
1)Swagger UI
http://localhost:9001/swagger-ui.html
2)Knife4j 增强 UI
http://localhost:9001/doc.html
当访问 knife4j 增强 UI 时,如果IDEA控制台报如下异常:
org.springframework.web.servlet.resource.NoResourceFoundException: No static resource favicon.ico.
咱们只需要提供一个图片,命名为 favicon.ico, 放在 src/main/resources/static 目录下,重启服务即可。
结语
本文咱们搭建了 agarwood-components-doc 模块,集成了 Knife4j + SpringDoc,实现了接口文档的自动生成,并集成在 VOC 服务中进行测试。
本文对应 commit 为:feat: 06 - Knife4j + SpringDoc 接口文档自动生成
按照惯例,如果你对本文内容有任何疑问或建议,欢迎在评论区留言讨论!

夜雨聆风
