swagger3(openapi 3.0)作为 api 文档生成工具,能帮助开发者快速构建清晰、可交互的 api 文档,减少前后端协作沟通成本。本文基于 springdoc-openapi 实现,详细介绍 swagger3 在 spring boot 项目中的基本使用方法、核心配置、常用注解及进阶优化方案。
一、项目环境与依赖配置
1. 环境要求
- spring boot 版本:2.7.x 及以上(兼容 spring boot 3.x)
- jdk 版本:1.8 及以上
2. 添加核心依赖
在项目 pom.xml 中引入 swagger3 核心依赖(springdoc-openapi 实现)和 knife4j 增强 ui 依赖(提供更友好的交互体验):
<!-- swagger3 核心依赖(springdoc 实现) -->
<dependency>
<groupid>org.springdoc</groupid>
<artifactid>springdoc-openapi-starter-webmvc-ui</artifactid>
<version>2.5.0</version> <!-- 稳定版本,与 spring boot 版本兼容 -->
</dependency>
<!-- knife4j 增强 ui(推荐,提供更友好的交互) -->
<dependency>
<groupid>com.github.xiaoymin</groupid>
<artifactid>knife4j-openapi3-jakarta-spring-boot-starter</artifactid>
<version>4.5.0</version>
</dependency>说明:若使用 spring boot 3.x,需确保依赖的
jakarta版本兼容,knife4j 4.5.0+ 已适配 spring boot 3.x。
二、swagger3 核心配置
1. 配置类编写
创建 swagger 配置类,定义 api 基本信息、安全方案、服务器环境等核心配置:
import io.swagger.v3.oas.models.openapi;
import io.swagger.v3.oas.models.info.contact;
import io.swagger.v3.oas.models.info.info;
import io.swagger.v3.oas.models.info.license;
import io.swagger.v3.oas.models.security.securityrequirement;
import io.swagger.v3.oas.models.security.securityscheme;
import io.swagger.v3.oas.models.servers.server;
import org.springframework.context.annotation.bean;
import org.springframework.context.annotation.configuration;
import java.util.arrays;
@configuration
public class swaggerconfig {
@bean
public openapi customopenapi() {
return new openapi()
// 1. api 基本信息配置
.info(new info()
.title("spring boot swagger3 demo api") // 文档标题
.version("1.0.0") // 接口版本
.description("这是一个 spring boot swagger3 示例项目,展示了 swagger3 的核心特性(注解使用、认证配置、多环境适配等)") // 文档描述
.contact(new contact() // 联系人信息
.name("example team")
.email("contact@example.com")
.url("http://example.com")
)
.license(new license() // 许可证信息
.name("apache 2.0")
.url("http://springdoc.org")
)
)
// 2. 安全方案配置(jwt bearer 认证)
.addsecurityitem(new securityrequirement().addlist("bearerauth"))
.components(new io.swagger.v3.oas.models.components()
.addsecurityschemes("bearerauth", new securityscheme()
.name("bearerauth")
.type(securityscheme.type.http)
.scheme("bearer")
.bearerformat("jwt")
)
)
// 3. 服务器环境配置(本地/测试/生产)
.servers(arrays.aslist(
new server().url("http://localhost:8080").description("本地开发环境"),
new server().url("https://staging.example.com").description("测试环境"),
new server().url("https://production.example.com").description("生产环境")
));
}
}2. 多环境配置(application-{profile}.properties)
通过配置文件控制不同环境是否启用 swagger(生产环境建议禁用,避免接口暴露):
开发环境(application-dev.properties)
# 启用 swagger3 文档 springdoc.swagger-ui.enabled=true springdoc.api-docs.enabled=true springdoc.openapi.enabled=true # swagger ui 优化配置 springdoc.swagger-ui.operations-sorter=alpha # 接口按字母排序(alpha=字母序,method=请求方法序) springdoc.swagger-ui.tags-sorter=alpha # 分组按字母排序 springdoc.swagger-ui.default-model-expand-depth=2 # 默认展开模型层级(2级) springdoc.swagger-ui.default-models-expand-depth=2 # 默认展开所有模型 springdoc.swagger-ui.path=/swagger-ui.html # 原生 swagger ui 访问路径 knife4j.enable=true # 启用 knife4j 增强 ui
生产环境(application-prod.properties)
# 生产环境禁用 swagger(安全考虑) springdoc.swagger-ui.enabled=false springdoc.api-docs.enabled=false springdoc.openapi.enabled=false knife4j.enable=false # 禁用 knife4j ui
三、常用注解与实战示例
swagger3 通过注解描述 api 接口、参数、响应和数据模型,以下是核心注解的实战用法(基于控制器和实体类):
1. 接口分组:@tag
用于标记控制器或接口组,方便文档分类展示,支持关联外部文档:
import io.swagger.v3.oas.annotations.tags.tag;
import io.swagger.v3.oas.annotations.externaldocs.externaldocumentation;
import org.springframework.web.bind.annotation.requestmapping;
import org.springframework.web.bind.annotation.restcontroller;
@restcontroller
@requestmapping("/api/users")
@tag(
name = "用户管理", // 分组名称(文档中显示的分组标签)
description = "用户相关核心接口,包含用户查询、创建、更新、删除等 crud 操作", // 分组描述
externaldocs = @externaldocumentation( // 外部文档链接(可选)
url = "http://example.com/docs/user-api",
description = "用户管理 api 详细设计文档"
)
)
public class usercontroller {
// 接口实现...
}2. 接口描述:@operation
用于描述具体接口的功能、用途,支持指定接口排序:
import io.swagger.v3.oas.annotations.operation;
import org.springframework.http.responseentity;
import org.springframework.web.bind.annotation.getmapping;
import org.springframework.web.bind.annotation.requestparam;
@operation(
summary = "分页查询所有用户", // 接口简要说明(文档列表页显示)
description = "支持按页码和每页大小分页,返回用户列表及分页信息(总条数、总页数)", // 详细描述
tags = {"用户管理"}, // 所属分组(与 @tag 名称一致)
position = 1 // 接口排序权重(数值越小越靠前)
)
@getmapping
public responseentity<pageresponse> getallusers(
@requestparam(defaultvalue = "1") integer page, // 页码(默认1)
@requestparam(defaultvalue = "10") integer size // 每页大小(默认10)
) {
// 业务逻辑:查询分页用户数据
page<user> userpage = userservice.listusers(page - 1, size); // page 从 0 开始
pageresponse pageresponse = new pageresponse<>(
userpage.getcontent(),
userpage.gettotalelements(),
userpage.gettotalpages(),
page,
size
);
return responseentity.ok(apiresponse.success(pageresponse));
}3. 请求参数描述:@parameter
用于描述请求参数(路径参数、查询参数、请求头),明确参数含义、示例值和约束:
import io.swagger.v3.oas.annotations.parameter;
import io.swagger.v3.oas.models.enums.parameterin;
import org.springframework.web.bind.annotation.getmapping;
import org.springframework.web.bind.annotation.pathvariable;
@operation(summary = "根据 id 查询用户", description = "通过用户唯一 id 获取用户详情", position = 2)
@getmapping("/{id}")
public responseentity<apiresponse> getuserbyid(
@parameter(
description = "用户唯一 id", // 参数说明
example = "1001", // 示例值(文档中可直接使用)
in = parameterin.path, // 参数位置:path/query/header
required = true, // 是否必填(默认 false)
name = "id" // 参数名称(与 @pathvariable 一致)
)
@pathvariable long id
) {
user user = userservice.getuserbyid(id);
if (user == null) {
return responseentity.ok(apiresponse.fail("用户不存在"));
}
return responseentity.ok(apiresponse.success(user));
}4. 响应说明:@apiresponses + @apiresponse
定义接口可能的响应状态码、描述和响应格式,帮助前端理解返回逻辑:
import io.swagger.v3.oas.annotations.responses.apiresponse;
import io.swagger.v3.oas.annotations.responses.apiresponses;
import io.swagger.v3.oas.annotations.media.content;
import io.swagger.v3.oas.annotations.media.schema;
import org.springframework.web.bind.annotation.postmapping;
import org.springframework.web.bind.annotation.requestbody;
@operation(summary = "创建用户", description = "新增用户信息,用户名不可重复", position = 3)
@apiresponses({
@apiresponse(
responsecode = "201", // 响应状态码(创建成功)
description = "用户创建成功",
content = @content(
mediatype = "application/json",
schema = @schema(implementation = apiresponse.class) // 响应数据模型
)
),
@apiresponse(responsecode = "400", description = "请求参数错误(如用户名长度不足、邮箱格式错误)"),
@apiresponse(responsecode = "409", description = "用户名已存在(冲突)"),
@apiresponse(responsecode = "500", description = "服务器内部错误")
})
@postmapping
public responseentity<apiresponse> createuser(
@requestbody user user // 请求体(下文详细描述)
) {
boolean success = userservice.createuser(user);
if (success) {
return responseentity.status(201).body(apiresponse.success(user));
}
return responseentity.ok(apiresponse.fail("创建失败"));
}5. 请求体描述:@requestbody
用于描述 post/put 等请求的请求体,明确请求格式、示例值和必填项:
import io.swagger.v3.oas.annotations.parameters.requestbody;
import io.swagger.v3.oas.annotations.media.exampleobject;
@postmapping
public responseentity<apiresponse> createuser(
@requestbody(
description = "用户创建请求参数",
required = true, // 是否必填
content = @content(
mediatype = "application/json",
examples = @exampleobject( // 请求体示例(文档中可直接复制使用)
name = "创建用户示例",
value = "{\"username\": \"test_user\", \"password\": \"123456a\", \"email\": \"test@example.com\", \"age\": 25, \"active\": true}"
),
schema = @schema(implementation = user.class) // 请求体数据模型
)
)
@org.springframework.web.bind.annotation.requestbody user user
) {
// 业务逻辑...
}6. 数据模型描述:@schema
用于描述实体类及其字段,明确字段含义、示例值、数据格式和约束:
import io.swagger.v3.oas.annotations.media.schema;
import lombok.data;
@data
@schema(description = "用户实体类(存储用户核心信息)")
public class user {
@schema(
description = "用户唯一 id",
example = "1001",
accessmode = schema.accessmode.read_only // 只读字段(创建时无需传入)
)
private long id;
@schema(
description = "用户名(登录账号)",
example = "admin",
requiredmode = schema.requiredmode.required, // 必填字段
minlength = 3, // 最小长度
maxlength = 20, // 最大长度
pattern = "^[a-za-z0-9_]+$" // 正则表达式(仅允许字母、数字、下划线)
)
private string username;
@schema(
description = "用户邮箱",
example = "admin@example.com",
format = "email", // 数据格式(邮箱格式校验)
requiredmode = schema.requiredmode.required
)
private string email;
@schema(
description = "用户年龄",
example = "28",
minimum = "1", // 最小值
maximum = "120", // 最大值
requiredmode = schema.requiredmode.not_required // 非必填
)
private integer age;
@schema(
description = "账号状态(true=启用,false=禁用)",
example = "true",
defaultvalue = "true" // 默认值
)
private boolean active;
}四、进阶功能配置
1. 全局参数配置
若项目中所有接口都需要携带固定参数(如 x-request-id 请求头),可在 swaggerconfig 中添加全局参数:
import io.swagger.v3.oas.models.parameters.parameter;
import io.swagger.v3.oas.models.media.schema;
import java.util.collections;
@bean
public openapi customopenapi() {
// 全局请求头参数:x-request-id(用于链路追踪)
parameter globalrequestid = new parameter()
.name("x-request-id")
.description("请求唯一标识(用于链路追踪)")
.in(parameterin.header)
.required(false)
.schema(new schema().example("req-20240520123456"));
return new openapi()
.info(...) // 原有信息配置
.addsecurityitem(...) // 原有安全配置
.components(...) // 原有组件配置
.servers(...) // 原有服务器配置
.addparametersitem(globalrequestid); // 添加全局参数
}2. 分组排序优化
通过 extensions 配置分组排序,让文档分组更符合业务逻辑:
import java.util.arrays;
import java.util.hashmap;
import java.util.collections;
@bean
public openapi customopenapi() {
return new openapi()
.info(...)
.addsecurityitem(...)
.components(...)
.servers(...)
// 分组排序配置
.extensions(collections.singletonmap(
"x-taggroups",
arrays.aslist(
new hashmap<string, object>() {{
put("name", "核心业务");
put("tags", arrays.aslist("用户管理", "订单管理"));
put("order", 1); // 分组排序权重(数值越小越靠前)
}},
new hashmap<string, object>() {{
put("name", "基础功能");
put("tags", arrays.aslist("产品管理", "系统配置"));
put("order", 2);
}}
)
));
}3. 忽略指定接口、参数
- 忽略接口:使用
@hidden注解(该接口不会显示在文档中)
import io.swagger.v3.oas.annotations.hidden;
@hidden
@getmapping("/internal") // 内部接口,不对外暴露
public responseentity() {
return responseentity.ok("内部接口返回");
}
- 忽略参数:在
@parameter中设置hidden = true
@getmapping("/info")
public responseentity<apiresponse>(
@parameter(hidden = true) // 隐藏该参数(不显示在文档中)
@requestparam string secretkey // 内部校验参数,无需前端关注
) {
// 业务逻辑...
}
4. 自定义响应示例(续)
@apiresponses({
@apiresponse(
responsecode = "200",
description = "操作成功",
content = @content(
mediatype = "application/json",
examples = @exampleobject(
name = "成功示例",
value = "{\"code\": 200, \"message\": \"操作成功\", \"data\": {\"id\": 1001, \"username\": \"admin\", \"email\": \"admin@example.com\"}}"
)
)
),
@apiresponse(
responsecode = "400",
description = "参数错误",
content = @content(
mediatype = "application/json",
examples = @exampleobject(
name = "参数错误示例",
value = "{\"code\": 400, \"message\": \"用户名长度不能小于3位\", \"data\": null}"
)
)
)
})
@postmapping
public responseentity<apiresponse> createuser(@requestbody user user) {
// 业务逻辑...
}
5. 集成 spring security 权限控制
若项目使用 spring security 进行权限管理,可通过 swagger 配置实现认证联动,让文档支持携带令牌访问受保护接口:
import io.swagger.v3.oas.models.security.oauthflow;
import io.swagger.v3.oas.models.security.oauthflows;
import io.swagger.v3.oas.models.security.scopes;
import org.springframework.context.annotation.bean;
import org.springframework.context.annotation.configuration;
@configuration
public class swaggerconfig {
@bean
public openapi customopenapi() {
return new openapi()
.info(...) // 原有信息配置
// 配置 oauth2 认证(密码模式)
.addsecurityitem(new securityrequirement().addlist("oauth2"))
.components(new io.swagger.v3.oas.models.components()
.addsecurityschemes("oauth2", new securityscheme()
.type(securityscheme.type.oauth2)
.flows(new oauthflows()
.password(new oauthflow()
.tokenurl("http://localhost:8080/oauth2/token") // 令牌获取地址
.scopes(new scopes()
.addstring("read", "读取权限")
.addstring("write", "写入权限")
)
)
)
)
)
.servers(...); // 原有服务器配置
}
}
补充:需在 spring security 配置中放行 swagger 相关路径,避免被拦截:
import org.springframework.context.annotation.bean;
import org.springframework.context.annotation.configuration;
import org.springframework.security.config.annotation.web.builders.httpsecurity;
import org.springframework.security.web.securityfilterchain;
@configuration
public class securityconfig {
@bean
public securityfilterchain filterchain(httpsecurity http) throws exception {
http.authorizehttprequests(auth -> auth
// 放行 swagger 相关路径
.requestmatchers("/swagger-ui/**", "/v3/api-docs/**", "/knife4j/**").permitall()
.anyrequest().authenticated()
);
return http.build();
}
}
五、文档访问与调试
1. 访问地址
配置完成后,启动项目,通过以下地址访问 swagger 文档:
- 原生 swagger ui:
http://localhost:8080/swagger-ui.html - knife4j 增强 ui(推荐):
http://localhost:8080/doc.html - openapi 规范 json:
http://localhost:8080/v3/api-docs
2. 在线调试流程
- 打开 knife4j ui 地址,在文档顶部选择对应的服务器环境(如本地开发环境);
- 若配置了认证(jwt/oauth2),点击页面右上角「授权」按钮,输入令牌或完成认证流程;
- 选择目标接口,点击「调试」按钮,填写请求参数(路径参数 / 查询参数 / 请求体);
- 点击「发送」按钮,查看响应结果(状态码、响应体、响应头)。
六、常见问题排查
1. 文档页面无法访问
- 检查
springdoc.swagger-ui.enabled和knife4j.enable配置是否为true(开发环境); - 确认依赖版本与 spring boot 版本兼容(如 spring boot 3.x 需使用 knife4j 4.5.0+);
- 排查 spring security 或拦截器是否拦截了 swagger 相关路径,需手动放行。
2. 接口未显示在文档中
- 检查控制器是否添加
@restcontroller注解,接口是否添加 http 注解(@getmapping/@postmapping等); - 确认接口方法是否为
public权限(非public方法不会被扫描); - 检查是否误加
@hidden注解,或是否配置了接口扫描范围限制。
3. 注解不生效
- 确认导入的是
io.swagger.v3.oas.annotations包下的注解(而非 swagger2 的io.swagger.annotations); - 检查依赖是否完整(核心依赖
springdoc-openapi-starter-webmvc-ui不可缺失)。
七、总结
swagger3(openapi 3.0)通过 springdoc-openapi 与 spring boot 项目无缝集成,仅需简单配置和注解,即可生成规范、可交互的 api 文档,大幅降低前后端协作成本。
核心优势
- 实时同步:接口变更时,文档自动更新,避免「文档与代码不一致」问题;
- 在线调试:支持直接在文档页面发送请求,无需依赖 postman 等第三方工具;
- 灵活扩展:支持 jwt/oauth2 认证、全局参数、分组排序等高级功能;
- 友好交互:knife4j 增强 ui 提供更直观的操作体验,支持文档导出(pdf/markdown)。
最佳实践
- 开发环境启用 swagger,生产环境强制禁用(避免接口暴露风险);
- 接口注解需完整(
@tag+@operation+@apiresponses),参数和模型添加@parameter/@schema说明; - 结合 spring security 配置权限控制,保障文档访问安全;
- 定期更新依赖版本,确保兼容性和安全性。
通过本文的配置和示例,开发者可快速上手 swagger3,并根据项目需求灵活扩展功能,让 api 文档成为前后端协作的「桥梁」而非「负担」。
到此这篇关于spring boot swagger3 使用指南的文章就介绍到这了,更多相关spring boot swagger3 使用内容请搜索代码网以前的文章或继续浏览下面的相关文章希望大家以后多多支持代码网!
发表评论