【SpringBoot】集成 Swagger


一、Swagger 核心概念

1.1 OpenAPI 规范与 Swagger 关系

OpenAPI Specification(OAS)是由 Linux 基金会主导的开源规范,用于标准化 RESTful API 的描述格式,当前主流版本为 3.0,是前后端协作、接口自动化测试的通用行业标准。

Swagger 是基于 OpenAPI 规范实现的一整套 API 开发工具链,可自动生成在线可交互接口文档,支持接口调试、参数校验、响应预览,彻底解决前后端分离架构下,接口文档维护滞后、手动编写易出错、团队沟通成本高的核心痛点。

复制代码
======= 🌟 青柠来相伴,代码更简单。🌟 =======
📚 本文所有内容,我都整理在了 青柠合集 里。👇
🎯 搜索关注【青柠代码录】,即可查看所有合集文章 ~
======= 🌟 =================== 🌟 =======

1.2 使用优势

  1. 代码即文档,实时同步:通过注解自动生成文档,代码修改后文档立即更新,彻底杜绝文档与实际接口不一致问题。
  2. 在线可视化调试:无需借助 Postman、ApiPost 等第三方工具,直接在文档页面发起请求、传入参数、查看完整响应。
  3. 跨语言兼容:支持 40+ 编程语言,适配单体应用、微服务、分布式架构等所有开发场景。
  4. 团队协作标准化:前端、测试、运维、产品统一依据文档工作,降低沟通歧义,提升研发效率。

二、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);
}

调试步骤:

  1. 打开 Swagger 文档
  2. 找到对应接口 → 点击 Try it out
  3. 填写请求参数 → 点击 Execute
  4. 查看响应码、响应体

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();
    }
}

五、安全规范

  1. 生产环境关闭 Swagger

    swagger:
    enabled: false

  2. 接口权限控制 :通过网关 / 安全框架拦截 /swagger-ui.html/v2/api-docs

  3. 敏感接口隐藏 :使用 @ApiIgnore 忽略核心内部接口

  4. 版本管理 :迭代升级时同步修改 version 版本号

本文由mdnice多平台发布

相关推荐
zhenxin012226 分钟前
GitSubmodule避坑指南:从入门到精通
spring boot·后端·spring
_Evan_Yao29 分钟前
缓存金字塔上的红色闪电:Redis 如何借力 CPU 的 L1/L2/L3 与 TLB 飞驰
java·数据库·redis·后端·缓存
0xDevNull1 小时前
分布式事务实战指南:从理论到Seata落地
java·开发语言·后端
sghuter1 小时前
数字资源分发的技术架构与未来趋势
c语言·开发语言·后端·青少年编程
Java编程爱好者1 小时前
深入解析 OpenJDK 17 在 Linux 上的线程创建机制
后端
Gopher_HBo1 小时前
数组和切片实战
后端
卷无止境1 小时前
过度设计如何避免(java举例)
后端
派星2 小时前
PageHelper 与 MyBatis 的分页查询协作原理
后端
卷无止境2 小时前
AI编程时代,什么需求使用rust开发最合适?
后端
lagrahhn3 小时前
ES索引的基础和进阶内容
后端·elasticsearch·搜索引擎