一、Swagger 核心概念
1.1 OpenAPI 规范与 Swagger 关系
OpenAPI Specification(OAS)是由 Linux 基金会主导的开源规范,用于标准化 RESTful API 的描述格式,当前主流版本为 3.0,是前后端协作、接口自动化测试的通用行业标准。
Swagger 是基于 OpenAPI 规范实现的一整套 API 开发工具链,可自动生成在线可交互接口文档,支持接口调试、参数校验、响应预览,彻底解决前后端分离架构下,接口文档维护滞后、手动编写易出错、团队沟通成本高的核心痛点。
======= 🌟 青柠来相伴,代码更简单。🌟 =======
📚 本文所有内容,我都整理在了 青柠合集 里。👇
🎯 搜索关注【青柠代码录】,即可查看所有合集文章 ~
======= 🌟 =================== 🌟 =======
1.2 使用优势
- 代码即文档,实时同步:通过注解自动生成文档,代码修改后文档立即更新,彻底杜绝文档与实际接口不一致问题。
- 在线可视化调试:无需借助 Postman、ApiPost 等第三方工具,直接在文档页面发起请求、传入参数、查看完整响应。
- 跨语言兼容:支持 40+ 编程语言,适配单体应用、微服务、分布式架构等所有开发场景。
- 团队协作标准化:前端、测试、运维、产品统一依据文档工作,降低沟通歧义,提升研发效率。
二、SpringBoot 快速集成 Swagger
2.1 依赖引入
方式一:spring4all 封装 Starter(极简集成,推荐)
<!-- SpringBoot 集成 Swagger 简化依赖 -->
<dependency>
<groupId>com.spring4all</groupId>
<artifactId>swagger-spring-boot-starter</artifactId>
<version>1.9.1.RELEASE</version>
</dependency>
方式二:原生 SpringFox 依赖(高度自定义场景)
<!-- Swagger2 核心依赖 -->
<dependency>
<groupId>io.springfox</groupId>
<artifactId>springfox-swagger2</artifactId>
<version>2.9.2</version>
</dependency>
<!-- Swagger UI 界面依赖 -->
<dependency>
<groupId>io.springfox</groupId>
<artifactId>springfox-swagger-ui</artifactId>
<version>2.9.2</version>
</dependency>
2.2 配置文件定义(YAML)
在 bootstrap.yml / application.yml 中添加 Swagger 全局配置:
swagger:
title: "青柠代码录 - 内容管理系统"
description: "青柠代码录项目,提供课程、分类、内容、权限等全流程管理接口"
base-package: com.qingning.content.controller # 必须配置:扫描Controller的包路径
enabled: true # 开发测试环境开启,生产环境关闭
version: 1.0.0
2.3 启用 Swagger
方式一:Starter 模式(启动类注解)
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import com.spring4all.swagger.EnableSwagger2Doc;
@SpringBootApplication
@EnableSwagger2Doc // 开启Swagger文档生成
public class QingNingContentApplication {
public static void main(String[] args) {
SpringApplication.run(QingNingContentApplication.class, args);
}
}
方式二:原生模式(配置类定义)
微服务多分组接口推荐使用:
package com.qingning.base.config;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import springfox.documentation.swagger2.annotations.EnableSwagger2;
import springfox.documentation.spring.web.plugins.Docket;
import springfox.documentation.service.ApiInfo;
import springfox.documentation.service.Contact;
import springfox.documentation.builders.ApiInfoBuilder;
import springfox.documentation.builders.RequestHandlerSelectors;
@Configuration
@EnableSwagger2
public class Swagger2Config {
/**
* 配置文档 docket 实例
*/
@Bean
public Docket adminApiConfig() {
return new Docket(DocumentationType.SWAGGER_2)
.groupName("content-api") // 接口分组名(微服务必备)
.apiInfo(adminApiInfo())
.select()
// 只扫描指定包下的Controller
.apis(RequestHandlerSelectors.basePackage("com.qingning.content.controller"))
.build();
}
/**
* 文档基础信息
*/
private ApiInfo adminApiInfo() {
return new ApiInfoBuilder()
.title("青柠代码录 - 内容管理接口文档")
.description("青柠代码录Java全栈实战项目接口定义")
.version("1.0.0")
.contact(new Contact("青柠代码录", "https://qingning.com", "qingning@163.com"))
.build();
}
}
2.4 访问接口文档
启动服务后访问固定地址:
http://localhost:端口号/服务上下文/swagger-ui.html
示例:
http://localhost:63040/content/swagger-ui.html
三、Swagger 核心注解
本部分为开发高频使用注解,全覆盖 Controller、接口方法、请求参数、响应实体、参数忽略等场景。
3.1 控制层(Controller)注解
1. @Api
-
作用:修饰整个 Controller 类,描述接口模块的业务功能
-
使用位置:类上方
-
核心属性:
-
tags:接口分组名称(文档左侧显示,支持中文) -
value:接口描述(简短说明) -
实战示例:
import io.swagger.annotations.Api;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.bind.annotation.RequestMapping;@Api(tags = "课程信息管理接口模块", value = "课程基础信息增删改查接口")
@RestController
@RequestMapping("/course")
public class CourseBaseInfoController {}
2. @ApiOperation
-
作用:修饰单个接口方法,描述接口用途、业务逻辑、注意事项
-
使用位置:方法上方
-
核心属性:
-
value:接口名称(简洁明了) -
notes:接口详细说明(业务逻辑、使用场景) -
实战示例:
import io.swagger.annotations.ApiOperation;
import org.springframework.web.bind.annotation.PostMapping;@ApiOperation(
value = "课程分页查询接口",
notes = "支持按课程名称、审核状态、发布状态进行条件分页查询,返回分页结果集"
)
@PostMapping("/list")
public PageResult<CourseBase> queryCourseList(PageParams pageParams, QueryCourseParamsDto dto) {
return null;
}
3. @ApiParam
-
作用 :修饰单个方法参数,对参数进行中文说明、必填标记
-
使用位置:方法参数前
-
核心属性:
-
value:参数说明 -
required:是否必填(true/false) -
example:参数示例值 -
实战示例:
@PostMapping("/get/{id}")
@ApiOperation("根据ID查询课程详情")
public CourseBase getCourseById(
@ApiParam(value = "课程ID", required = true, example = "1001")
@PathVariable Long id
) {
return null;
}
4. @ApiImplicitParams + @ApiImplicitParam
-
作用 :批量描述 简单请求参数(非实体类参数)
-
使用位置:方法上方
-
适用场景:GET 请求、表单参数
-
实战示例:
@GetMapping("/page")
@ApiOperation("课程简单分页查询")
@ApiImplicitParams({
@ApiImplicitParam(name = "pageNo", value = "当前页码", dataType = "Long", defaultValue = "1"),
@ApiImplicitParam(name = "pageSize", value = "每页条数", dataType = "Long", defaultValue = "10")
})
public PageResult<CourseBase> page(Long pageNo, Long pageSize) {
return null;
}
5. @ApiIgnore
-
作用:让 Swagger 忽略该类 / 接口,不生成文档
-
使用场景:内部接口、测试接口、敏感接口
-
实战示例:
@ApiIgnore
@GetMapping("/test")
public String test() {
return "test";
}
3.2 实体层(DTO/VO/Entity)注解
1. @ApiModel
- 作用:修饰实体类,描述该实体的业务用途
- 使用位置:类上方
- 核心属性 :
description:实体说明
2. @ApiModelProperty
-
作用:修饰实体字段,描述字段含义、示例、必填性
-
核心属性:
-
value:字段中文说明 -
example:字段示例值 -
required:是否必填 -
hidden:是否隐藏该字段 -
实战示例:
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;@Data
@ApiModel(description = "课程查询条件DTO")
public class QueryCourseParamsDto {@ApiModelProperty(value = "审核状态:UNREVIEWED-未审核 REVIEWED-已审核", example = "UNREVIEWED") private String auditStatus; @ApiModelProperty(value = "课程名称,支持模糊查询", example = "Java全栈开发") private String courseName; @ApiModelProperty(value = "发布状态:PUBLISHED-已发布 UNPUBLISHED-未发布", example = "UNPUBLISHED") private String publishStatus;}
分页参数实体:
@Data
@ApiModel(description = "通用分页请求参数")
public class PageParams {
@ApiModelProperty(value = "当前页码", example = "1", defaultValue = "1")
private Long pageNo = 1L;
@ApiModelProperty(value = "每页记录数", example = "10", defaultValue = "10")
private Long pageSize = 10L;
}
3.3 响应相关注解
1. @ApiResponses + @ApiResponse
-
作用:描述接口响应状态码与业务含义
-
实战示例:
@PostMapping("/add")
@ApiOperation("新增课程接口")
@ApiResponses({
@ApiResponse(code = 200, message = "新增成功"),
@ApiResponse(code = 500, message = "服务异常,新增失败"),
@ApiResponse(code = 400, message = "参数校验失败")
})
public Result addCourse(@RequestBody CourseBase dto) {
return Result.success();
}
3.4 注解速查表(收藏版)
| 注解 | 作用对象 | 核心用途 |
|---|---|---|
| @Api | Controller 类 | 定义接口模块名称 |
| @ApiOperation | 接口方法 | 定义接口名称、详细说明 |
| @ApiParam | 方法参数 | 单个参数描述、必填标记 |
| @ApiImplicitParams | 接口方法 | 批量定义简单参数 |
| @ApiImplicitParam | 注解内部 | 单个参数名称、类型、说明 |
| @ApiModel | 实体类 | 定义 DTO/VO 业务含义 |
| @ApiModelProperty | 实体字段 | 定义字段说明、示例、是否必填 |
| @ApiIgnore | 类 / 方法 | 忽略接口,不生成文档 |
| @ApiResponses | 接口方法 | 定义接口所有响应状态码 |
| @ApiResponse | 注解内部 | 单个响应码 + 说明 |
四、常见问题
4.1 Swagger 在线调试实战
@ApiOperation("课程分页查询接口")
@PostMapping("/list")
public PageResult<CourseBase> list(PageParams pageParams, @RequestBody(required = false) QueryCourseParamsDto dto) {
// 模拟业务数据
CourseBase course = new CourseBase();
course.setCourseName("青柠代码录 - Java全栈实战");
course.setAuditStatus("UNREVIEWED");
course.setCreateDate(LocalDateTime.now());
List<CourseBase> list = Collections.singletonList(course);
return new PageResult<>(list, 1, 1, 10);
}
调试步骤:
- 打开 Swagger 文档
- 找到对应接口 → 点击 Try it out
- 填写请求参数 → 点击 Execute
- 查看响应码、响应体
4.2 LocalDateTime 格式化问题
Swagger 默认序列化 LocalDateTime 格式为时间戳,需自定义格式化:
package com.qingning.base.config;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.module.SimpleModule;
import com.fasterxml.jackson.datatype.jsr310.deser.LocalDateTimeDeserializer;
import com.fasterxml.jackson.datatype.jsr310.ser.LocalDateTimeSerializer;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.http.converter.json.Jackson2ObjectMapperBuilder;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
@Configuration
public class LocalDateTimeConfig {
private static final String PATTERN = "yyyy-MM-dd HH:mm:ss";
@Bean
public ObjectMapper objectMapper() {
Jackson2ObjectMapperBuilder builder = new Jackson2ObjectMapperBuilder();
SimpleModule module = new SimpleModule();
// 序列化:LocalDateTime → String
module.addSerializer(LocalDateTime.class, new LocalDateTimeSerializer(DateTimeFormatter.ofPattern(PATTERN)));
// 反序列化:String → LocalDateTime
module.addDeserializer(LocalDateTime.class, new LocalDateTimeDeserializer(DateTimeFormatter.ofPattern(PATTERN)));
builder.modules(module);
return builder.build();
}
}
五、安全规范
-
生产环境关闭 Swagger
swagger:
enabled: false -
接口权限控制 :通过网关 / 安全框架拦截
/swagger-ui.html、/v2/api-docs -
敏感接口隐藏 :使用
@ApiIgnore忽略核心内部接口 -
版本管理 :迭代升级时同步修改
version版本号
本文由mdnice多平台发布