Spring 应用中 Swagger 2.0 迁移 OpenAPI 3.0 详解:配置、注解与实践

从 Swagger 2.0 到 OpenAPI 3.0 的升级指南

为什么升级

OpenAPI 3.0提供了更强大的功能、更简洁的配置和更好的性能,同时保持了与 Swagger 2.0 的基本兼容性。本文将详细介绍升级的各个步骤,并提供代码示例。

1. 依赖管理的变化

Swagger 2.0 依赖配置

<dependency><groupId>io.springfox</groupId><artifactId>springfox-swagger2</artifactId><version>2.9.2</version>
</dependency>
<dependency><groupId>io.springfox</groupId><artifactId>springfox-swagger-ui</artifactId><version>2.9.2</version>
</dependency>

OpenAPI 3.0 依赖配置

<dependency><groupId>org.springdoc</groupId><artifactId>springdoc-openapi-starter-webmvc-ui</artifactId><version>2.2.0</version>
</dependency>

关键变化:

  • 从多个 springfox 依赖简化为单一的 springdoc 依赖
  • 自动集成 Swagger UI 和 OpenAPI 规范生成
  • 无需手动管理多个依赖版本

2. 配置类的重构

Swagger 2.0 配置类

import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import springfox.documentation.builders.ApiInfoBuilder;
import springfox.documentation.builders.PathSelectors;
import springfox.documentation.builders.RequestHandlerSelectors;
import springfox.documentation.service.ApiInfo;
import springfox.documentation.spi.DocumentationType;
import springfox.documentation.spring.web.plugins.Docket;
import springfox.documentation.swagger2.annotations.EnableSwagger2;@Configuration
@EnableSwagger2
public class SwaggerConfig {@Beanpublic Docket api() {return new Docket(DocumentationType.SWAGGER_2).select().apis(RequestHandlerSelectors.basePackage("com.example.controller")).paths(PathSelectors.any()).build().apiInfo(apiInfo());}private ApiInfo apiInfo() {return new ApiInfoBuilder().title("Swagger 2.0 API").description("API documentation using Swagger 2.0").version("1.0.0").build();}
}

OpenAPI 3.0 配置类

import io.swagger.v3.oas.models.OpenAPI;
import io.swagger.v3.oas.models.info.Info;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;@Configuration
public class OpenAPIConfig {@Beanpublic OpenAPI customOpenAPI() {return new OpenAPI().info(new Info().title("OpenAPI 3.0 API").description("API documentation using OpenAPI 3.0").version("1.0.0"));}
}

关键变化:

  • 移除了 @EnableSwagger2 注解
  • 不再需要手动配置 Docket 和选择器
  • 使用 OpenAPI 类直接定义 API 元数据
  • 自动扫描控制器和模型,无需指定包路径

3. 注解系统的升级

控制器注解对比

Swagger 2.0OpenAPI 3.0 替代方案
@Api@Tag
@ApiOperation@Operation
@ApiParam@Parameter
@ApiResponses@Operationresponses 属性
@ApiIgnore@Parameter(hidden = true)

模型注解对比

Swagger 2.0OpenAPI 3.0 替代方案
@ApiModel@Schema
@ApiModelProperty@Schema

示例:控制器注解升级

// Swagger 2.0 控制器
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import io.swagger.annotations.ApiParam;
import org.springframework.web.bind.annotation.*;@RestController
@RequestMapping("/api/users")
@Api(value = "User Management API", description = "Operations related to users")
public class UserControllerV2 {@ApiOperation(value = "Retrieve a user by ID", response = User.class)@GetMapping("/{id}")public User getUserById(@ApiParam(value = "User ID", required = true) @PathVariable Long id) {return userService.findById(id);}
}// OpenAPI 3.0 控制器
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.*;@RestController
@RequestMapping("/api/users")
@Tag(name = "User Management API", description = "Operations related to users")
public class UserControllerV3 {@Operation(summary = "Retrieve a user by ID",description = "Returns a single user identified by the provided ID")@GetMapping("/{id}")public User getUserById(@Parameter(description = "User ID", required = true) @PathVariable Long id) {return userService.findById(id);}
}

4. 数据模型注解的更新

Swagger 2.0 模型定义

import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;@ApiModel(description = "Represents a user in the system")
public class User {@ApiModelProperty(value = "Unique identifier for the user", example = "1")private Long id;@ApiModelProperty(value = "User's full name", example = "John Doe")private String name;@ApiModelProperty(value = "User's email address", example = "john@example.com")private String email;
}

OpenAPI 3.0 模型定义

import io.swagger.v3.oas.annotations.media.Schema;public class User {@Schema(description = "Unique identifier for the user", example = "1", required = true)private Long id;@Schema(description = "User's full name", example = "John Doe", minLength = 2)private String name;@Schema(description = "User's email address", example = "john@example.com", format = "email")private String email;
}

增强功能:

  • 支持更丰富的 format 选项(如 email, date, uuid 等)
  • 直接在 @Schema 中定义约束条件(如 minLength, maxLength
  • 更好的与 JSON Schema 集成

5. 安全配置的升级

Swagger 2.0 安全配置

@Bean
public Docket api() {return new Docket(DocumentationType.SWAGGER_2).securitySchemes(Arrays.asList(apiKey())).securityContexts(Arrays.asList(securityContext()));
}private ApiKey apiKey() {return new ApiKey("JWT", "Authorization", "header");
}private SecurityContext securityContext() {return SecurityContext.builder().securityReferences(defaultAuth()).forPaths(PathSelectors.regex("/api/.*")).build();
}private List<SecurityReference> defaultAuth() {AuthorizationScope authorizationScope = new AuthorizationScope("global", "accessEverything");AuthorizationScope[] authorizationScopes = new AuthorizationScope[1];authorizationScopes[0] = authorizationScope;return Arrays.asList(new SecurityReference("JWT", authorizationScopes));
}

OpenAPI 3.0 安全配置

@Bean
public OpenAPI customOpenAPI() {return new OpenAPI().info(new Info().title("API").version("1.0.0")).components(new Components().addSecuritySchemes("bearerAuth", new SecurityScheme().type(SecurityScheme.Type.HTTP).scheme("bearer").bearerFormat("JWT"))).addSecurityItem(new SecurityRequirement().addList("bearerAuth"));
}

关键改进:

  • 简化的安全方案定义
  • 支持更多安全类型(如 OAuth2、OpenID Connect)
  • 更清晰的安全要求声明

6. 处理特殊场景

自定义扩展

// Swagger 2.0 自定义扩展
@Bean
public Docket customImplementation() {return new Docket(DocumentationType.SWAGGER_2).extensions(customVendorExtensions());
}private List<VendorExtension> customVendorExtensions() {List<VendorExtension> extensions = new ArrayList<>();VendorExtension<String> extension = new VendorExtension() {@Overridepublic String getName() {return "x-custom-info";}@Overridepublic String getValue() {return "This is a custom extension";}};extensions.add(extension);return extensions;
}// OpenAPI 3.0 自定义扩展
@Bean
public OpenAPI customOpenAPI() {return new OpenAPI().info(new Info().title("API").version("1.0.0").addExtension("x-custom-info", "This is a custom extension"));
}

分组 API 文档

// OpenAPI 3.0 分组配置
@Configuration
public class OpenAPIConfig {@Beanpublic GroupedOpenApi userApi() {return GroupedOpenApi.builder().group("users").pathsToMatch("/api/users/**").build();}@Beanpublic GroupedOpenApi productApi() {return GroupedOpenApi.builder().group("products").pathsToMatch("/api/products/**").build();}
}

7. 验证升级结果

  1. 访问 Swagger UI
    • 旧路径:http://localhost:8080/swagger-ui.html(已失效)
    • 新路径:http://localhost:8080/swagger-ui/index.html

8. 常见问题与解决方案

  1. 依赖冲突

    • 确保移除所有 springfox 相关依赖
    • 使用 Maven 的 dependency:tree 或 Gradle 的 dependencies 命令检查冲突
  2. UI 无法访问

    • 确认 springdoc-openapi-starter-webmvc-ui 依赖已正确添加
    • 检查是否有自定义 Web 配置拦截了 /swagger-ui/** 路径
  3. 注解不生效

    • 确认使用的是 io.swagger.v3.oas.annotations 包下的注解
    • 检查类路径是否存在旧版本注解
  4. 性能问题

    • OpenAPI 3.0 通常比 Swagger 2.0 更快,但大型项目可能需要配置:
      springdoc.api-docs.enabled=true
      springdoc.swagger-ui.enabled=true
      

总结

从 Swagger 2.0 升级到 OpenAPI 3.0 是一个相对直接的过程,主要涉及依赖替换、配置重构和注解更新。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。
如若转载,请注明出处:http://www.pswp.cn/web/89359.shtml
繁体地址,请注明出处:http://hk.pswp.cn/web/89359.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

用 Flink CEP 打造实时超时预警:从理论到实战

目录 1. Flink CEP 是什么?为什么它能让你的数据“开口说话”? 2. 超时预警的业务场景:从电商到物联网 3. Flink CEP 超时机制的核心原理 3.1 模式匹配与时间窗口 3.2 超时事件的处理 3.3 事件时间与水位线 3.4 核心组件一览 4. 实战案例:电商订单超时预警 4.1 准备…

Rocky Linux 9 源码包安装php7

Rocky Linux 9 源码包安装php7大家好&#xff01;我是星哥。尽管现在 PHP 版本已迭代至 8.x&#xff0c;但有时为了兼容遗留系统或特定应用需求&#xff0c;我们仍需部署特定版本的 PHP。最主要的是之前的项目采用的PHP7.3&#xff0c;未来兼容旧的项目&#xff0c; 今天&#…

uniapp+vue3+鸿蒙系统的开发

前言&#xff1a; uniappvue3鸿蒙系统的开发。 实现效果&#xff1a; 鸿蒙pad端真机测试效果-下面是正常的日志效果 实现步骤&#xff1a; 1、安装鸿蒙的开发工具&#xff0c;点击安装&#xff0c;注意版本不能太旧了 deveco-studio 2、下载下来是个压缩包&#xff0c;解压后…

【C++类和对象解密】面向对象编程的核心概念(下)

之前我们了解到构造函数是在对象实例化之时对对象完成初始化工作的一个函数。在我们不写时&#xff0c;编译器会自动生成构造函数。构造函数有一些特点&#xff0c;比如&#xff0c;他对内置类型不做处理&#xff0c;对自定义类型的成员会去调用其自身的构造。我们上篇文章还提…

Flutter基础(前端教程①②-序列帧动画)

&#x1f9e0; 核心思路总结​​彻底绕过 Image组件重建带来的性能瓶颈​​&#xff1a;不再让 setState重建包含 Image的 Widget 树&#xff08;这是开销大、可能导致闪烁的根源&#xff09;&#xff0c;改为使用底层画布 (Canvas) 直接绘制预先处理好的图像帧数据。好的&…

Qt添加dmp文件生成及pdb文件

1.Pdb文件生成 下图先通过构建生成Pdb文件&#xff0c;然后运行程序&#xff0c;通过提前准备的崩溃按钮使得程序崩溃&#xff0c;生成“dump文件”的演示。 # #添加dmp文件生成及pdb文件生成DEFINES QT_MESSAGELOGCONTEXT DEFINES QT_DEPRECATED_WARNINGS# # 添加DUMP文件…

opencv、torch、torchvision、tensorflow的区别

一、框架定位与核心差异PyTorch动态计算图&#xff1a;实时构建计算图支持Python原生控制流&#xff08;如循环/条件&#xff09;&#xff0c;调试便捷。学术主导&#xff1a;2025年工业部署份额24%&#xff0c;适合快速原型开发&#xff08;如无人机自动驾驶、情绪识别&#x…

离散与组合数学 杂记

生成函数 概念 又称母函数把一个无穷数列 {an}\{a_n\}{an​}&#xff08;默认从 000 项起&#xff09;表示成 G(x)∑i≥0aixiG(x)\displaystyle\sum_{i\ge0} a_ix^iG(x)i≥0∑​ai​xi 的函数形式。例如&#xff1a; ai2ia_i2^iai​2i&#xff1a;G(x)∑i≥02ixiG(x)\display…

学习OpenCV---显示图片

学习OpenCV—显示图片 最近在学习OpenCV入门&#xff0c;于是记录一下自己的学习过程。 一、配置环境 第一步 从官方网站中下载OpenCV开源库。官方下载网站 打开官网后&#xff0c;能看到有很多的版本。我个人下载的是4.11.0版本。点击图中的下载 下载完成后&#xff0c;解…

第一次接触自动化监测,需要付费厂家安装服务吗?比人工测量主要区别是啥?

人工检测是依靠目测检查或借助于便携式仪器测量得到的信息&#xff0c;但是随着整个行业的发展&#xff0c;传统的人工检测方法已经不能满足检测需求&#xff0c;从人工检测到自动化监测已是必然趋势。 a. 从检测方式看 人工检测需要耗费大量的精力&#xff0c;从摆放检测工具到…

VMware Workstation Pro 17下载安装

注册账号 进入下载地址&#xff1a;Free Downloads - Support Portal - Broadcom support portal - https://support.broadcom.com/ 会让注册账号&#xff0c;注册一个就行 在右上角 下载 地址&#xff1a;Free Downloads - Support Portal - Broadcom support portal - ht…

SpringBoot 3.x集成阿里云OSS:文件上传 断点续传 权限控制

SpringBoot 3.x集成阿里云OSS&#xff1a;文件上传&#xff0f;断点续传&#xff0f;权限控制Spring Boot 3.x 集成阿里云 OSS 终极指南一、环境准备与依赖配置1. 添加阿里云 OSS SDK 依赖2. 配置 OSS 连接参数二、基础文件上传服务1. OSS 客户端配置2. 文件上传服务三、断点续…

牛客周赛 Round 100

A小红的双排列没什么好说的 直接 1 1 2 2 3 3 4 4……#define _CRT_SECURE_NO_WARNINGS #include<stdio.h> #include<iostream> #include<bits/stdc.h> #define ll long long using namespace std; int n; int main(){ios::sync_with_stdio(false); …

【Dv3Admin】菜单管理集成阿里巴巴自定义矢量图标库

图标选择是后台管理系统中高频功能。相比用 Element UI、Ant Design 等自带的 icon 集&#xff0c;阿里巴巴 iconfont.cn 支持上传和管理自定义图标&#xff0c;并生成矢量字体&#xff0c;便于统一维护和扩展。 本文目标是支持自定义 iconfont 图标的展示和选择&#xff0c;并…

NO.7数据结构树|线索二叉树|树森林二叉树转化|树森林遍历|并查集|二叉排序树|平衡二叉树|哈夫曼树|哈夫曼编码

线索二叉树 线索二叉树的基本概念 为了解决无法直接找到该结点在某种遍历序列中的前驱和后继结点的问题&#xff0c; 出现了线索二叉树。 一个二叉树通过如下的方法“穿起来” &#xff1a; 所有原本为空的右(孩子)指针改为指向该节点在某种遍历序列中的后继&#xff0c; 所有原…

R语言基础| 基本图形绘制(条形图、堆积图、分组图、填充条形图、均值条形图)

目录 一、前言 二、条形图 1. 简单的条形图 2.堆积、分组和填充条形图(柱状图) &#xff08;1&#xff09;堆积图&#xff0c;对Improved进行堆积&#xff0c;注意position“stack” &#xff08;2&#xff09;分组图&#xff0c;对Improved进行分组&#xff0c;注意posit…

SegNet:一种用于图像分割的深度卷积编码器解码器架构

教程/讲解视频点击文末名片1、什么是语义分割&#xff0c;什么是FCN 我们提出了一种新颖且实用的深度全卷积神经网络架构&#xff0c;用于语义像素级分割&#xff0c;命名为SegNet。 语义分割是指为图像中的每个像素分配一个类别标签&#xff08;如道路、天空、汽车&#xff09…

PyTorch 数据加载全攻略:从自定义数据集到模型训练

目录 一、为什么需要数据加载器&#xff1f; 二、自定义 Dataset 类 1. 核心方法解析 2. 代码实现 三、快速上手&#xff1a;TensorDataset 1. 代码示例 2. 适用场景 四、DataLoader&#xff1a;批量加载数据的利器 1. 核心参数说明 2. 代码示例 五、实战&#xff1…

Python--plist文件的读取

Python练习&#xff1a;读取Apple Plist文件 Plist文件简介 ​​定义​​&#xff1a;Apple公司创建的基于XML结构的文件格式​​特点​​&#xff1a;采用XML语法组织数据&#xff0c;可存储键值对、数组等结构化信息文件扩展名​​&#xff1a;.plist应用场景: ​​iOS系统:​…

JAVA几个注解记录

在Java中&#xff0c;Data、AllArgsConstructor和NoArgsConstructor是Lombok库提供的注解&#xff0c;用于自动生成Java类中的样板代码&#xff08;如getter、setter、构造函数等&#xff09;&#xff0c;从而减少冗余代码&#xff0c;提高开发效率。以下是它们的详细功能和使用…