第 57 章:OpenAPI 文档
学习目标
- 集成 springdoc-openapi
- 学会用注解描述接口
- 给 Swagger UI 设置安全
一、集成
xml
<dependency>
<groupId>org.springdoc</groupId>
<artifactId>springdoc-openapi-starter-webmvc-ui</artifactId>
<version>2.3.0</version>
</dependency>访问:
- Swagger UI:http://localhost:8080/swagger-ui.html
- OpenAPI JSON:http://localhost:8080/v3/api-docs
二、基础配置
💡 这段配置干啥的? SpringDoc 启动时读这个 bean 生成 Swagger UI(
/swagger-ui.html)。.info()是文档标题/版本(纯展示),.addSecuritySchemes()是给 Swagger UI 配 token 入口(点 "Try it out" 时自动带 JWT)。
java
@Configuration // ① Spring 配置类
public class OpenApiConfig {
@Bean // ② 注册成 bean(SpringDoc 启动会读它)
public OpenAPI customOpenAPI() {
return new OpenAPI()
.info(new Info() // ③ 接口文档基本信息(Swagger UI 顶部展示)
.title("我的 API")
.version("1.0")
.description("项目接口文档"))
.components(new Components() // ④ 可复用组件
.addSecuritySchemes("bearer-jwt", // ⑤ 定义鉴权方案叫 bearer-jwt
new SecurityScheme()
.type(SecurityScheme.Type.HTTP) // 类型:HTTP
.scheme("bearer") // 模式:Bearer(请求头带 token)
.bearerFormat("JWT"))); // token 格式:JWT(只是文档提示)
}
}⑤ addSecuritySchemes 的实际效果:
┌────────────────────────────────────┐
│ Authorize │
│ bearer-jwt [eyJhbGciOi...填这] │
│ [Authorize] [Cancel] │
└────────────────────────────────────┘
↓ 填完一次
所有接口自动带 Authorization: Bearer xxx
↓
点 "Try it out" 直接调通(不用手动加 token)三、注解
java
@Operation(summary = "创建用户", description = "根据 DTO 创建用户")
@ApiResponses({
@ApiResponse(responseCode = "200", description = "成功"),
@ApiResponse(responseCode = "400", description = "参数错误"),
@ApiResponse(responseCode = "401", description = "未登录")
})
@PostMapping("/users")
public Result<UserVO> create(@RequestBody @Valid UserDTO dto) { }
@Tag(name = "用户管理", description = "用户 CRUD 接口")
@RestController
@RequestMapping("/users")
public class UserController { }💡 这些注解不改变代码运行行为,只是告诉 Swagger UI 这个接口叫什么、返回啥、可能返回啥错。
| 注解 | 干嘛 | Swagger UI 哪里显示 |
|---|---|---|
@Operation | 描述单个接口(summary + description) | 接口名旁边显示标题 |
@ApiResponses | 列出这个接口可能返回的所有状态码 | 文档里"Responses"区域 |
@Tag | 把一类接口分组(加在 Controller 类上) | 顶部"Tags"分类(用户管理 / 订单管理 ...) |
Swagger UI 跑起来长这样:
用户管理 (Tag 分组)
├─ POST /users 创建用户
│ summary: 创建用户
│ description: 根据 DTO 创建用户
│ 请求体: UserDTO { name, email, ... }
│ 响应:
│ 200: 成功
│ 400: 参数错误
│ 401: 未登录关键点:
- 注解纯文档,不运行时——不写这些接口照样跑,只是 Swagger UI 上看着空
@ApiResponses写全可能的状态码,前端看文档就知道 401 是没登录要重新登录
字段描述:
java
@Schema(description = "用户名")
private String username;
@Schema(description = "年龄", example = "18", minimum = "0", maximum = "150")
private Integer age;四、Swagger 启用条件
yaml
springdoc:
api-docs:
enabled: true
swagger-ui:
enabled: true
paths-to-match: /api/** # 只扫 /api/ 下生产关闭!
yaml
springdoc:
api-docs:
enabled: false
swagger-ui:
enabled: false⚠️ 坑 1:生产环境必须关 Swagger,否则接口完全暴露,任何人都能调到。
五、分组
啥时候要分组?啥时候不用?
| 场景 | 需不需要分组 |
|---|---|
| 接口少(几十个) | 不用,一个 group 都装得下,分组反而多一层下拉框,徒增切换成本 |
| 接口多(几百个) | 建议分,全塞一个里翻起来累 |
| 多端(前后台 / 小程序 / App) | 必须分,每端一套路径前缀,前端只看自己的不串 |
| 多团队协作(支付 / 订单 / 商品各管一摊) | 建议分,Swagger UI 上按团队/模块切,互不干扰 |
⚠️ 判断标准很简单:接口少/单端/单人项目都不用分——加分组只会多一个右上角下拉框,没收益。等接口破百、多端共用一套后端、或者团队分模块时再加即可。
java
@Bean
public GroupedOpenApi publicApi() {
return GroupedOpenApi.builder()
.group("public") // ① 分组名:Swagger UI 右上角下拉框里显示的文字
.pathsToMatch("/api/public/**") // ② 只扫 /api/public/ 开头的接口塞进这组
.build();
}
@Bean
public GroupedOpenApi adminApi() {
return GroupedOpenApi.builder()
.group("admin") // ① 分组名:另一个组
.pathsToMatch("/api/admin/**") // ② 只扫 /api/admin/ 开头的接口塞进这组
.build();
}Swagger UI 上长这样(右上角下拉框):
┌────────────────────────────────────┐
│ Select a group ▼ [public] │ ← 默认选第一个
│ ├─ public │
│ ├─ admin │ ← 切到 admin,就只显示 /api/admin/** 的接口
│ └─ (其他组) │
└────────────────────────────────────┘关键点:
- 多个
@Bean一起注册 = 自动多组,不用写配置类把它们串起来 pathsToMatch是路径前缀匹配,可以是数组(.pathsToMatch("/api/admin/**", "/api/internal/**"))- 路径互斥才好用,如果两个组的
pathsToMatch有重叠,接口在两组都会出现
六、DTO 兼容(Java 8 时间)
xml
<dependency>
<groupId>com.fasterxml.jackson.datatype</groupId>
<artifactId>jackson-datatype-jsr310</artifactId>
</dependency>yaml
spring:
jackson:
serialization:
write-dates-as-timestamps: false
date-format: yyyy-MM-dd HH:mm:ss七、本章小结
| 要点 | 关键 |
|---|---|
| 集成 | springdoc-openapi-starter-webmvc-ui |
| 注解 | @Operation / @Tag / @Schema |
| 生产 | 必须关 Swagger |
| 路径匹配 | paths-to-match 配置 |
动手练习
- 给现有 controller 加 OpenAPI 注解
- 配置 JWT 安全,Swagger UI 也能带 token 调
下一章:第 58 章:幂等性与防重复提交 →