Spring Boot 整合 Swagger 与 OpenAPI 3 自动生成接口文档怎么做?

来源:JS教程作者:清原小日向头衔:网络博主
导读:本期聚焦于清原小日向创作的《Spring Boot 整合 Swagger 与 OpenAPI 3 自动生成接口文档怎么做?》,敬请观看详情。接口文档手写维护成本高,还容易和代码不一致,团队协作时经常因此扯皮。Spring Boot 项目其实可以借助 springdoc-openapi 这个库,让接口文档根据代码注解自动生成,并且完全兼容 OpenAPI 3 规范。本文将介绍 springdoc-openapi 的引入方式、常用注解的用法、分组配置以及界面汉化等技巧,同时对比旧版 springfox 的差异,说明为什么新项目建议直接使用 OpenAPI 3 方案。文末还会给出生产环境隐藏文档、安全控制等实用建议,帮助你快速搭建一套规范、易维护的接口文档体系。

做后端开发,接口文档几乎绕不开。传统做法是在项目里单独维护一份 Word 或者 Markdown 文档,接口一多、需求一改,文档就和代码脱节了,前端同事照着旧文档调接口,报错了才发现在害人害己。Swagger 解决的就是这个问题:它根据代码里的注解自动渲染出一份可视化的接口文档,代码改了文档跟着变,还能在页面上直接调试接口。这篇文章以 Spring Boot 项目为例,完整讲一下如何用 springdoc-openapi 整合 OpenAPI 3 规范,从引入依赖到注解配置再到分组与权限控制,一次性说清楚。

Spring Boot 整合 Swagger 与 OpenAPI 3 自动生成接口文档怎么做?

一、为什么选择 springdoc-openapi 而不是 springfox

老一点的 Spring Boot 项目里,Swagger 整合基本都用 springfox 这个库。但 springfox 有一个致命问题:它的最后一个稳定版本 3.0.0 发布后基本停止维护了,对新版 Spring Boot 2.6 以上的支持很差。因为 Spring Boot 2.6 开始默认把路径匹配策略改成了 PathPatternParser,而 springfox 依赖的 AntPathMatcher 与之冲突,启动时会直接抛出 NullPointerException,很多开发者不得不额外配置 spring.mvc.pathmatch.matching-strategy=ant_path_matcher 来绕过,这本质上是在开倒车。

springdoc-openapi 是社区目前主推的替代方案,它原生支持 OpenAPI 3 规范(springfox 主要停留在 Swagger 2 / OpenAPI 2),对新版本的 Spring Boot 和 Spring WebFlux 都有良好支持,而且配置更简单,常用功能开箱即用,不需要像 springfox 那样写一大堆 Docket 配置。对于新项目,直接选 springdoc-openapi 就对了。

两者的核心区别在于数据格式:Swagger 2 使用 JSON 描述接口,而 OpenAPI 3 规范更完善,支持一个接口多种请求体类型、更丰富的 Schema 定义。目前主流的 API 网关、Mock 工具、代码生成器(比如 openapi-generator)都已经全面拥抱 OpenAPI 3,跟着规范走,生态兼容性会好很多。

二、引入依赖与基础配置

以 Spring Boot 2.7.x 为例,在 pom.xml 中加入如下依赖即可:

<dependency>
    <groupId>org.springdoc</groupId>
    <artifactId>springdoc-openapi-ui</artifactId>
    <version>1.7.0</version>
</dependency>

注意版本匹配:Spring Boot 2.x 要用 springdoc-openapi 1.x 系列,访问路径是 /swagger-ui.html;如果是 Spring Boot 3.x,则要换成 springdoc-openapi-starter-webmvc-ui(2.x 系列),并且 UI 路径变成了 /swagger-ui/index.html。这个版本对应关系搞错了,页面会直接 404,是新手最常踩的坑之一。

引入依赖后不做任何配置,启动项目就能看到文档了,Controller 里的接口会自动被扫描出来。当然一般我们会补充一些全局信息,通过一个配置类来实现:

import io.swagger.v3.oas.models.OpenAPI;
import io.swagger.v3.oas.models.info.Info;
import io.swagger.v3.oas.models.info.Contact;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

@Configuration
public class SwaggerConfig {

    @Bean
    public OpenAPI customOpenAPI() {
        return new OpenAPI().info(new Info()
                .title("订单系统接口文档")
                .version("1.0")
                .description("提供订单、商品相关的全部 REST 接口")
                .contact(new Contact().name("后端团队").email("dev@ipipp.com")));
    }
}

另外也可以在 application.yml 里做精细控制,常用的几个配置项如下:

springdoc:
  api-docs:
    enabled: true          # 是否开启 /v3/api-docs 端点
    path: /v3/api-docs     # 接口描述 JSON 的路径
  swagger-ui:
    enabled: true
    path: /swagger-ui.html
  packages-to-scan: com.example.order.controller  # 限定扫描包,避免把非接口类扫进来

packages-to-scan 这个配置很有用,项目规模大了以后,如果不对扫描范围加以限制,一些内部的工具 Controller 也会出现在文档里,既混乱又不安全。

三、常用注解详解与示例

自动扫描只能拿到接口路径和参数类型,要让文档真正可读,还得靠注解补充描述。OpenAPI 3 的注解都在 io.swagger.v3.oas.annotations 包下,和 Swagger 2 的注解完全是两套体系,迁移时注意逐个替换。下面通过一个完整的 Controller 示例来看最常用的几个注解:

import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.Parameter;
import io.swagger.v3.oas.annotations.tags.Tag;
import org.springframework.web.bind.annotation.*;

@Tag(name = "订单管理", description = "订单的创建、查询与取消")
@RestController
@RequestMapping("/api/order")
public class OrderController {

    @Operation(summary = "根据ID查询订单", description = "返回订单的完整信息,包括商品明细")
    @GetMapping("/{id}")
    public OrderVO getOrder(
            @Parameter(description = "订单ID", example = "10001")
            @PathVariable Long id) {
        return orderService.getById(id);
    }

    @Operation(summary = "创建订单")
    @PostMapping
    public Long createOrder(@RequestBody OrderCreateDTO dto) {
        return orderService.create(dto);
    }
}

注解的职责可以这样理解:@Tag 用在类上做接口分组,页面上左侧菜单按它归类;@Operation 用在方法上,summary 是接口名,description 是详细说明;@Parameter 描述单个参数。对于 @RequestBody 的实体类,则要在 DTO 上用 @Schema 注解:

import io.swagger.v3.oas.annotations.media.Schema;
import java.math.BigDecimal;

@Schema(description = "创建订单的请求参数")
public class OrderCreateDTO {

    @Schema(description = "商品ID", example = "88", requiredMode = Schema.RequiredMode.REQUIRED)
    private Long productId;

    @Schema(description = "购买数量", example = "2", minimum = "1")
    private Integer quantity;

    @Schema(description = "订单金额", example = "199.00")
    private BigDecimal amount;

    // 省略 getter/setter
}

这里有个细节要提一下:字段上如果加了 JSR-303 校验注解(比如 @NotNull@Min(1)),springdoc 会自动把它们体现在文档的必填标记和取值范围上,不需要重复声明。所以建议 DTO 该加校验注解就加,一举两得。另外,统一返回结果类(比如 Result<T> 这种泛型包装)建议配合 @Schema 的 implementations 属性明确指定泛型类型,否则文档里的响应结构会丢失泛型信息,显示成 Object。

四、接口分组与生产环境安全控制

项目里如果同时存在后台管理接口和面向 App 的接口,全部堆在一个文档页面会很难找。springdoc 提供了 GroupedOpenApi 支持按路径或包拆分多个分组:

import org.springdoc.core.GroupedOpenApi;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

@Configuration
public class GroupConfig {

    @Bean
    public GroupedOpenApi adminApi() {
        return GroupedOpenApi.builder()
                .group("后台管理")
                .pathsToMatch("/api/admin/**")
                .build();
    }

    @Bean
    public GroupedOpenApi appApi() {
        return GroupedOpenApi.builder()
                .group("移动端")
                .pathsToMatch("/api/app/**")
                .build();
    }
}

配置完成后,Swagger UI 页面右上角会出现分组下拉框,前端同事可以按需切换,体验提升明显。

还有一个容易被忽视的问题是安全。Swagger 页面本身是一个暴露所有接口细节的入口,如果生产环境不加控制地开放,等于把系统的接口清单拱手送给别人,攻击者能很方便地找到未做鉴权的接口。推荐的做法是分环境配置:开发环境开启,生产环境关闭,通过 Maven profile 或配置中心的变量来控制:

springdoc:
  api-docs:
    enabled: ${swagger.enabled:false}
  swagger-ui:
    enabled: ${swagger.enabled:false}

这样只有当 swagger.enabled 显式设为 true 时文档才可用,生产环境的配置里不设置这个变量即可。如果确实需要在测试环境保留文档,同时又要防止任意访问,可以结合 Spring Security 对 /swagger-ui/**/v3/api-docs/** 路径做认证拦截,只放行内部网段或指定账号。

最后补充一个小技巧:springdoc 默认生成的界面是英文的,如果希望汉化,可以自行下载 swagger-ui 的静态资源放入项目的 src/main/resources/META-INF/resources/webjars/ 目录下覆盖默认文件,并修改其中的文案。对于内部团队使用来说,这个工作量不大,但对文档的可读性帮助不小。整体来看,用 springdoc-openapi 整合 OpenAPI 3 的成本非常低,基本就是加依赖、写注解两步,换来的是文档与代码永远一致,这笔账怎么算都划算。

Spring BootSwaggerOpenAPI 3接口文档修改时间:2026-09-09 09:31:08

免责声明:已尽一切努力确保本网站所含信息的准确性。网站作品多为原创整理与精心创作,观点力求客观中立。本站旨在免费分享,内容仅供个人学习、研究或参考使用。若引用了第三方作品,版权归原作者所有。如内容涉及您的权益,请联系我们进行处理Email:chomcom@qq.com。
引用或转载本作品时,请注明当前出处:https://www.ipipp.com/html/20260909/53322.html,基于非商业用途的前提下,欢迎转载或二创本作品。
内容垂直聚焦
专注技术核心技术栏目,确保每篇文章深度聚焦于实用技能。从代码技巧到架构设计,为用户提供无干扰的纯技术知识沉淀,精准满足专业提升需求。
知识结构清晰
覆盖从开发到部署的全链路。AI、前端、编程、数据库、服务器、建站、系统层层递进,构建清晰学习路径,帮助用户系统化掌握开发与运维所需的核心技术。
深度技术解析
拒绝泛泛而谈,深入技术细节与实践难点。无论是数据库优化还是服务器配置,均结合真实场景与代码示例进行剖析,致力于提供可直接应用于工作的解决方案。
专业领域覆盖
精准对应开发生命周期。从前端界面到后端编程,从数据库操作到服务器运维,形成完整闭环,一站式满足全栈工程师和运维人员的技术需求。
即学即用高效
内容强调实操性,步骤清晰、代码完整。用户可根据教程直接复现和应用于自身项目,显著缩短从学习到实践的距离,快速解决开发中的具体问题。
持续更新保障
专注既定技术方向进行长期、稳定的内容输出。确保各栏目技术文章持续更新迭代,紧跟主流技术发展趋势,为用户提供经久不衰的学习价值。