一,介绍
Swagger 3 通常指的是 OpenAPI 3.0 及更高版本,它是一个开放的API描述规范,用于标准化RESTful API的设计、文档化和测试。通过编写符合OpenAPI规范的YAML或JSON文件,开发者可以清晰地定义API的接口、参数、返回值、鉴权方式等细节,并自动生成交互式文档、客户端/服务端代码,甚至进行接口测试。
核心功能与价值
- 标准化设计:统一API描述格式,避免团队协作中的沟通歧义。
- 自动生成文档:通过工具(如Swagger UI)生成可视化、可交互的API文档。
- 代码生成:根据规范自动生成服务端和客户端代码(支持多种语言)。
- 接口测试:结合工具(如Postman、Swagger Inspector)直接调试API。
- 生态支持:与主流开发框架(Spring Boot、FastAPI等)深度集成。
发展历程
- Swagger的诞生(2011-2015)
- 2011年:由Tony Tam等人开发,最初是Wordnik公司的API框架(Scala语言)的副产品,目的是解决API文档维护问题。
- 2011-2014年:推出Swagger 1.x,逐渐成为最流行的API文档工具之一。
- 2014年:发布Swagger 2.0,规范更简洁,工具生态(Swagger UI、Swagger Editor等)成熟。
- 转型为OpenAPI(2015-2017)
- 2015年:Swagger规范捐赠给Linux基金会,成立OpenAPI Initiative(OAI),联合Google、IBM等大厂共同维护。
- 2017年:发布OpenAPI 3.0(即Swagger 3),彻底重构规范,支持更复杂的API场景。
- OpenAPI 3.x时代(2017至今)
- 2021年:发布OpenAPI 3.1,兼容JSON Schema 2020-12,进一步强化灵活性和扩展性。
- 现状:OpenAPI已成为API领域的行业标准,Swagger工具集(如Swagger UI)仍是其生态的重要组成部分。
Swagger与OpenAPI的关系
- Swagger:指原始规范和工具集(如Swagger UI、Swagger Codegen)。
- OpenAPI:规范的官方名称,由OAI维护,Swagger工具集支持OpenAPI规范。
- 常见误解:
- “Swagger 3”是OpenAPI 3.0的非官方叫法。
- Swagger工具(如Swagger UI)可以解析OpenAPI 2.0/3.x文件。
SpringDoc
Springdoc 是 Spring Boot 应用与 Swagger 3(OpenAPI 3.0+)集成的核心工具,它通过自动化解析 Spring 的注解和代码结构,生成符合 OpenAPI 3.0 规范的 API 文档,并与 Swagger UI 等工具无缝结合。
Springdoc 的作用与定位
- 核心功能:
- 将 Spring Boot 中的控制器(
@RestController)、方法(@GetMapping/@PostMapping等)和模型(@Schema)自动转换为 OpenAPI 3.0 规范的文档描述(YAML/JSON)。 - 集成 Swagger UI,提供可视化、交互式的 API 文档界面。
- 支持 OpenAPI 3.0+ 的高级特性(如多服务器配置、鉴权方案、Webhooks 等)。
- 将 Spring Boot 中的控制器(
- 与 Swagger 3(OpenAPI 3.0)的关系:
Springdoc 是 实现 OpenAPI 3.0 规范的工具,而 Swagger 3 是规范本身。
- Springdoc 依赖 OpenAPI 3.0 的规则解析代码结构。
- 最终生成的文档遵循 OpenAPI 3.0 格式,并通过 Swagger UI 展示。
为什么需要 Springdoc?
- 历史背景: Swagger 早期在 Spring 生态中的实现是 Springfox(支持 Swagger 2.0),但它对 OpenAPI 3.0 的支持滞后且维护不足。 Springdoc 应运而生,专注于 全面支持 OpenAPI 3.0+,且与 Spring Boot 3+ 兼容性更好。
- 关键优势:
- 零配置启动:仅需添加依赖,即可自动扫描 Spring 控制器生成文档。
- 注解驱动:通过
@Operation、@Parameter、@Schema等注解精细控制文档细节。 - 与 Spring 生态深度集成:支持 Spring Web MVC、Spring WebFlux、Spring Security 等模块。
与旧版 Springfox 的对比
| 特性 | Springdoc(OpenAPI 3.0+) | Springfox(Swagger 2.0) |
|---|---|---|
| 规范支持 | 全面支持 OpenAPI 3.0/3.1 | 仅支持 Swagger 2.0(OpenAPI 2.0) |
| 维护状态 | 活跃维护(GitHub 1k+ stars) | 已停止维护(官方推荐迁移到 Springdoc) |
| Spring Boot 3+ 兼容性 | 完全兼容 | 不兼容 |
| 配置复杂度 | 更简洁(自动扫描 + 注解驱动) | 需手动配置 Docket 等对象 |
二,快速入门
-
添加依赖
<dependency> <groupId>org.springdoc</groupId> <artifactId>springdoc-openapi-starter-webmvc-ui</artifactId> <version>2.3.0</version> </dependency> -
编写第一个接口
import io.swagger.v3.oas.annotations.Operation; import io.swagger.v3.oas.annotations.Parameter; import io.swagger.v3.oas.annotations.tags.Tag; @RestController @Tag(name = "示例接口", description = "简单的问候 API") public class HelloController { @Operation( summary = "打招呼", description = "根据传入的名称返回问候语", parameters = @Parameter(name = "name", description = "用户名称", example = "Alice") ) @GetMapping("/hello") public String sayHello(@RequestParam(required = false, defaultValue = "World") String name) { return "Hello, " + name + "!"; } } -
开启openapi
# swagger-ui custom path springdoc: api-docs: # 开启Swagger的doc文档 enabled: true path: /docs swagger-ui: # 启用Swagger UI enabled: true path: /api-docs -
启动应用
运行 Spring Boot 主类,访问以下 URL:Swagger UI 界面:http://localhost:8080/api-docs
三,相关注解
3.1 类级别注解
@Tag
-
用途:定义接口分组(类似 Swagger 2.0 的
@Api),用于在 Swagger UI 中将多个接口归类到同一标签下。 -
常用属性:
name:标签名称(必填,唯一标识)。description:标签描述。externalDocs:附加外部文档链接。
-
示例:
@RestController @Tag(name = "用户管理", description = "用户增删改查接口") public class UserController { // ... }
3.2 方法级别注解
@Operation
- 用途:描述单个接口方法(如 GET、POST)的元数据。
- 关键属性:
summary:接口摘要(简洁标题)。description:详细描述。tags:覆盖类级别的@Tag分组。parameters:定义接口参数(可与方法参数上的@Parameter结合使用)。responses:自定义响应状态码和描述。
- 示例:
@Operation( summary = "创建用户", description = "根据传入的 User 对象创建新用户", responses = { @ApiResponse(responseCode = "201", description = "用户创建成功"), @ApiResponse(responseCode = "400", description = "请求参数无效") } ) @PostMapping("/users") public User createUser(@RequestBody User user) { /* ... */ }
@ApiResponses / @ApiResponse
- 用途:定义接口的响应状态码和说明(通常与
@Operation配合)。 - 属性:
responseCode:HTTP 状态码(如 "200")。description:状态码描述。content:指定响应内容类型和模型(使用@Content)。
- 示例:
@Operation(summary = "获取用户详情") @ApiResponses({ @ApiResponse(responseCode = "200", description = "成功返回用户数据", content = @Content(schema = @Schema(implementation = User.class))), @ApiResponse(responseCode = "404", description = "用户不存在") }) @GetMapping("/users/{id}") public User getUser(@PathVariable Long id) { /* ... */ }
3.3 参数级别注解
@Parameter
- 用途:描述接口的请求参数(路径参数、查询参数、请求头等)。
- 关键属性:
name:参数名(需与代码中的变量名一致)。description:参数说明。required:是否必填(默认false)。schema:参数的数据类型和约束(如@Schema)。in:参数位置(path,query,header,cookie)。
- 示例:
@GetMapping("/search") public List<User> searchUsers( @Parameter( name = "keyword", description = "搜索关键词", required = true, schema = @Schema(type = "string", minLength = 2) ) @RequestParam String keyword, @Parameter( name = "page", description = "分页页码", schema = @Schema(type = "integer", minimum = "1", defaultValue = "1") ) @RequestParam(defaultValue = "1") int page ) { /* ... */ }
@RequestBody
- 用途:描述请求体的结构和内容(通常与
@Schema配合)。 - 示例:
@PostMapping("/users") public User createUser( @io.swagger.v3.oas.annotations.parameters.RequestBody( description = "用户数据", required = true, content = @Content( schema = @Schema(implementation = User.class), examples = @ExampleObject( name = "示例请求", value = "{\"name\": \"Alice\", \"age\": 25}" ) ) ) @RequestBody User user ) { /* ... */ }
3.4 模型与字段注解
@Schema
- 用途:定义数据模型(DTO、实体类)及其字段的元数据。
- 常用属性:
title:模型标题。description:详细描述。required:标记必填字段(如required = true)。example:示例值。type:数据类型(自动推断,通常无需手动指定)。minimum/maximum:数值范围约束。
- 示例:
@Schema(name = "User", description = "用户实体") public class User { @Schema(description = "用户ID", example = "1001", minimum = "1") private Long id; @Schema(description = "用户姓名", required = true, minLength = 2) private String name; @Schema(description = "用户年龄", example = "25", minimum = "0", maximum = "150") private Integer age; }
@ArraySchema
- 用途:描述数组或集合类型的字段。
- 示例:
@Schema(description = "用户列表") @ArraySchema( arraySchema = @Schema(description = "用户数组"), schema = @Schema(implementation = User.class) ) private List<User> users;
3.5 其他注解
@Hidden
- 用途:隐藏接口、模型或字段,不生成文档。
- 示例:
@Hidden // 隐藏整个接口 @RestController public class InternalController { /* ... */ } public class User { @Hidden // 隐藏敏感字段(如密码) private String password; }
@ExampleObject
- 用途:为请求或响应提供示例数据。
- 示例:
@Operation(summary = "创建用户") @ApiResponse( responseCode = "201", content = @Content( mediaType = "application/json", examples = @ExampleObject( name = "成功示例", value = "{\"id\": 1, \"name\": \"Alice\"}" ) ) ) @PostMapping("/users") public User createUser(@RequestBody User user) { /* ... */ }
四,配置相关
4.1 基础配置类(OpenAPI 信息)
@Configuration
public class OpenApiConfig {
@Bean
public OpenAPI customOpenAPI() {
return new OpenAPI()
.info(new Info()
.title("测试 API")//标题
.version("1.0.0")//api的版本
.description("测试接口文档")//描述信息
.contact(new Contact()
.name("技术支持")//联系方式等
.email("support@example.com"))
.license(new License()
.name("Apache 2.0")//许可证信息
.url("https://www.apache.org/licenses/LICENSE-2.0")));
}
}
4.2 分组配置
import org.springdoc.core.models.GroupedOpenApi;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
@Configuration
public class GroupConfig {
// 用户接口分组
@Bean
public GroupedOpenApi userApi() {
return GroupedOpenApi.builder()
.group("用户接口")
.pathsToMatch("/api/user/**") // 匹配路径规则
.packagesToScan("com.example.user") // 指定扫描包(可选)
.build();
}
// 管理接口分组
@Bean
public GroupedOpenApi adminApi() {
return GroupedOpenApi.builder()
.group("管理接口")
.pathsToMatch("/api/admin/**")
.build();
}
}
通配符
| 通配符 | 说明 |
|---|---|
? | 匹配单个字符(如 /api/v? 匹配 /api/v1、/api/v2,但不匹配 /api/v12) |
* | 匹配同一层路径中的任意字符(如 /api/* 匹配 /api/user,不匹配 /api/user/1) |
** | 跨路径层级匹配任意字符(如 /api/** 匹配所有以 /api/ 开头的路径) |
4.3 使用 Profile 动态加载配置类
通过 @Profile 注解限制 Swagger 配置类仅在非生产环境生效:
@Configuration
@Profile("!prod") // 仅在非生产环境(如 dev、test)生效
public class OpenApiConfig {
@Bean
public OpenAPI customOpenAPI() {
return new OpenAPI().info(new Info().title("开发环境 API"));
}
@Bean
public GroupedOpenApi userApi() {
return GroupedOpenApi.builder()
.group("用户接口")
.pathsToMatch("/api/**")
.build();
}
}
4.4 接口排序
4.4.1 基础排序规则
Swagger UI 默认的排序规则:
- 标签(Tags):按接口的
@Tag名称字母顺序排序。 - 接口(Operations):按接口路径(Path)字母顺序排序。
4.4.2 通过 YAML 配置排序
在 application.yml 中配置以下参数,调整排序逻辑:
-
按字母顺序排序
springdoc: swagger-ui: tags-sorter: alpha # 标签按字母顺序排序(默认) operations-sorter: alpha # 接口按路径字母顺序排序(默认) -
按方法排序(GET/POST/PUT/DELETE)
springdoc: swagger-ui: operations-sorter: method # 接口按 HTTP 方法排序(GET → POST → PUT → DELETE) -
按路径层级排序
springdoc: swagger-ui: operations-sorter: path # 接口按路径层级深度排序(如 /a → /a/b → /a/b/c)
五,整合Knife4j框架
5.1 介绍
Knife4j的前身是swagger-bootstrap-ui,前身swagger-bootstrap-ui是一个纯swagger-ui的ui皮肤项目。
Knife4j不仅仅将前身的Ui皮肤通过Vue技术栈进行了重写,也增加了更多个性化的特性增强功能,基于springfox项目以及OpenAPI的规范
目前主要支持以Java开发为主,并且是依赖于大环境下使用的Spring MVC、Spring Boot、Spring Cloud框架.
5.2 集成Knife4j
-
导包
<dependency> <groupId>com.github.xiaoymin</groupId> <artifactId>knife4j-openapi3-jakarta-spring-boot-starter</artifactId> <version>4.5.0</version> </dependency>注意:knife4j依赖了springdoc,不需要俩个都引入,引入这个一个即可
-
编写配置文件
# Knife4j 增强配置 knife4j: enable: true # 启用 Knife4j setting: language: zh-CN # 中文界面 enable-swagger-models: true # 显示模型(Model) enable-document-manage: true # 启用文档管理配置了这个就别配置springdoc了,knife4j完全兼容的
-
编写网页数据内容以及分组
这里的分组,元数据编写是和Springdoc完全一致的
@Configuration public class OpenApiConfig { @Bean public OpenAPI customOpenAPI() { return new OpenAPI() .info(new Info() .title("测试 API")//标题 .version("1.0.0")//api的版本 .description("测试接口文档")//描述信息 .contact(new Contact() .name("技术支持")//作者 .email("support@example.com")) .license(new License() .name("Apache 2.0")//许可证信息 .url("https://www.apache.org/licenses/LICENSE-2.0"))); } // 用户接口分组 @Bean public GroupedOpenApi userApi() { return GroupedOpenApi.builder() .group("api1分组") .pathsToMatch("/api1/**") .build(); } // 管理接口分组 @Bean public GroupedOpenApi adminApi() { return GroupedOpenApi.builder() .group("api2分组") .pathsToMatch("/api2/**") .build(); } }