【OpenAPI】Spring3 集成 OpenAPI 生成接口文档

Spring3 集成 OpenAPI 生成接口文档

1. 依赖

Spring 版本:3.0.5

Java 版本:jdk21

OpenAPI 依赖:

<!-- https://mvnrepository.com/artifact/org.springdoc/springdoc-openapi-starter-webmvc-ui -->
<dependency><groupId>org.springdoc</groupId><artifactId>springdoc-openapi-starter-webmvc-ui</artifactId><version>2.6.0</version>
</dependency>

官网:OpenAPI 规范 | OpenAPI 官方文档中文版 (xiniushu.com)

不要包含其他的接口文档的框架,大概率是冲突的

目前我还没有找到 Spring3 的其他接口文档方案,swagger2 和 swagger3 都因为不兼容搞不了;

2. 配置文件

默认整个类路径全扫描

@Configuration
public class OpenApiConfig {@Beanpublic OpenAPI springOpenAPI() {return new OpenAPI().info(new Info().title("SpringDoc API Test").description("SpringDoc Simple Application Test").version("1.0"));}}

3. 关键用法

3.1 Tag 注解

对接口文档进行分组,一个 controller 类为单位

@RestController
@RequiredArgsConstructor
@RequestMapping("/api/v1")
@Tag(name = "xxx")
public class xxxController {}

3.2 Operation 注解

对接口进行描述,一个目标方法为单位

@PostMapping("/create")
@Operation(summary = "创建一个 XXX")
public SystemJsonResponse<CustomClass> createXXX() {}

3.3 Parameter 与 Header 注解

Parameter 描述一个接口的参数与路径参数,Header 描述一个接口的请求头,他们作用于目标方法的形参

@PostMapping("/get/{id}")
@Operation(summary = "获得一个 XXX")
public SystemJsonResponse<CustomClass> getXXX(@RequestHeader("token") @Header(description = "token") String token,@PathVariable("id") @Parameter(description = "id") Long id,@RequestParam(name = "state") @Parameter(description = "state") Integer state) {
}

3.4 Schema 注解

Schema 描述一个数据模型,也可以描述一个属性,作用于类或者字段

name 可指定属性的名称,description 是属性的描述

name 作为数据模型(类)的名称,description 是数据模型(类)的描述

属性得 public 或者有 public 的 Getter 和 Setter,否则会被标注只读或只写,如果都没有则直接忽略,如果一个数据模型属性都没有,忽略这个数据模型,复杂点的情况还会出现莫名其妙的现象

总而言之规范地写就没问题,框架也没义务和精力去控制各种奇奇怪怪地情况,我们也没必要总结

@TableName(value ="user")
@Schema(description = "用户")
@Data
public class User implements Serializable {@Schema(description = "ID")private Long id;@Schema(description = "昵称")private String nickname;private static final long serialVersionUID = 1L;
}

3.5 SchemaProperty 注解

SchemaProperty 作用于一个字段,无法设置属性名,name 作为属性的描述

这个注解不能作用于自定义的数据模型,自定义对象会被认定为 string,因为这个注解就是作用于普通的字段,并不支持递归扫描,这个时候应该用 Schema

  • 建议都用 Schema,SchemaProperty 功能还是太弱了
@SchemaProperty(name = "ID")
private Long id;

3.6 Hidden

作用于字段,表示忽略字段

@Hidden
private String nickname;

3.7 nullable = true

注解参数设置这个代表参数可以为 null

@Schema(description = "昵称", nullable = true)
private String nickname;

3.8 响应的数据模型

OpenAPI 提供了 @ApiRespnse 注解,但是很不方便,不如直接去 Postman 或者 Apifox 上进行操作,理想状态就是直接扫描出「请求body对象」和「响应body对象」 Schema 注解描述的数据模型

请求的话,作为参数是类型是确定的,OpenAPI 框架自然是扫描的到的,但是响应的数据模型,一般是统一响应格式的:

@Schema(name = "统一响应")
@NoArgsConstructor
@Getter
public class SystemJsonResponse implements Serializable {private static final long serialVersionUID = 1L;@JsonInclude@Schema(description = "状态码")private int code;@JsonInclude@Schema(description = "描述语")private String message;@JsonInclude@Schema(nullable = true)private Object data;
}

返回的时候,构造 json 是没问题的,但是框架扫描不出来这个 data 数据模型,因为框架只知道 data 是 Object 类型

你可能想问:“框架拿到 data 用 getClass 不就知道了吗?”

是的,但是接口文档生成是在这个接口被调用之前,所以并没有一个 data 数据提供给框架

你很容易想到用范型来定义统一响应:

@Schema(name = "统一响应")
@NoArgsConstructor
@Getter
public class SystemJsonResponse<T> implements Serializable {private static final long serialVersionUID = 1L;@JsonInclude@Schema(description = "状态码")private int code;@JsonInclude@Schema(description = "描述语")private String message;@JsonInclude@Schema(nullable = true)private T data;
}

但是实践这个方式,你会发现生成的接口文档,data 仍然是 object

其实原因很简单,用 @Schema 将 SystemJsonResponse 描述作一个固定的数据模型,那每个以此对象为返回值的目标方法,接口文档都直接使用这个数据模型

而泛型在定义的时候,本质还是 Object

解决方案也很简单,去掉 @Schema 即可,这样框架扫描目标方法返回的 SystemJsonResponse<CustomClass> 的时候,都会创建一个新的数据模型,这个时候就可以通过泛型类型确定准确的响应数据模型了,若存在一个一模一样的才会复用

注意:

  1. 不支持通配符:SystemJsonResponse<?>
  2. SystemJsonResponse<? extends CustomClass>,则仅仅扫描 CustomClass

3.9 补充

GetMapping 的接口,RequestBody 会被扫描成 queryString,而不是 json

4. 访问

http://[host]:[post]/swagger-ui/index.html

http://[host]:[post]/v3/api-docs

在这里插入图片描述

更多细节需要去查去探索这里不一一罗列

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

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

相关文章

JetLinks物联网学习(前后端项目启动)

前后端项目启动 1、后端1.1 pgsql改mysql报错2、elasticSearch7.0版本以上_doc格式取消 2、前端 1、后端 环境准备&#xff1a; 1、window系统7,8&#xff0c;10 。 硬件资源最低要求4c8G&#xff0c;硬盘40G 2、JDK 1.8.0_2xx (需要小版本号大于200) 3、Maven3.6.3 4、Redis …

渗透测试入门学习——php表单form与POST、GET请求练习

最终效果&#xff1a; 必填项为空报错提示&#xff1a; 代码&#xff1a; <!DOCTYPE html> <html lang"en"> <head><meta charset"UTF-8"><title>php表单练习</title> </head> <body> <?php//php中的…

二十种编程语言庆祝中秋节

二十种编程语言庆祝中秋节 文章目录 二十种编程语言庆祝中秋节中秋快乐&#xff01;家人们 &#x1f973;一 Python二 C三 C四 Java五 C#六 Perl七 Go八 Asp九 PHP十 JavaScript十一 JavaScript HTML十二 Visual Basic十三 早期 VB十四 Visual C十五 Delphi十六 Shell十七 Cobo…

教程 | ArcGIS Pro如何自动保存数据编辑内容

目录 1、工程自动保存 2、数据编辑自动保存 世界上最痛苦的事情就是&#xff1a; 软件崩溃&#xff0c;我没保存&#xff01;&#xff01;&#xff01; 电脑死机&#xff0c;我没保存&#xff01;&#xff01;&#xff01; 突然断电&#xff0c;我没保存&#xff01;&…

Vue2知识点

注意:笔记内容来自网络 1Vue指令 指令是指&#xff1a;带有v-前缀的特殊标签属性 1.1 v-html v-html&#xff08;类似 innerHTML&#xff09; 使用语法&#xff1a;<p v-html"intro">hello</p>&#xff0c;意思是将 intro 值渲染到 p 标签中 类似 i…

深入理解Docke工作原理:UnionFS文件系统详解

在容器技术的世界中&#xff0c;文件系统的设计和实现是其关键组成部分&#xff0c;影响着镜像的构建效率、容器的启动速度以及资源的利用率。**UnionFS&#xff08;联合文件系统&#xff09;**作为Docker的核心文件系统技术&#xff0c;通过其独特的分层结构和写时复制&#x…

Matlab simulink建模与仿真 第十三章(信号通路库)

参考视频&#xff1a;simulink1.1simulink简介_哔哩哔哩_bilibili 一、信号通路库中的模块概览 1、信号通路组 注&#xff1a;部分模块在第二章中有介绍&#xff0c;本章不再赘述。 2、信号存储和访问组 二、总线分配模块 Bus Assignment模块接受总线作为输入&#xff0c;并…

集群软件在linux上的安装

前置准备 为了保证各个服务器之间的正常通信&#xff0c;要完成集群化环境的前置准备&#xff0c;包括创建多台虚拟机&#xff0c;配置主机名映射&#xff0c;SSH免密登录等等。 配置多个虚拟机 配置多台Linux虚拟机 安装集群化软件&#xff0c;首要条件就是要有多台Linux服务…

GaussDB关键技术原理:高弹性(五)

书接上文GaussDB关键技术原理&#xff1a;高弹性&#xff08;四&#xff09;从扩容流程框架方面对hashbucket扩容技术进行了解读&#xff0c;本篇将从日志多流和事务相关方面继续介绍GaussDB高弹性技术。 目录 4.2 日志多流 4.2.1 日志多流总体流程 4.2.2 基线数据传输 4.…

CleanClip vs 传统剪贴板:究竟谁更胜一筹?

在日常工作和生活中,复制粘贴可以说是我们使用最频繁的操作之一。传统的剪贴板功能虽然简单易用,但在功能性和效率上还有很大的提升空间。今天,我们就来比较一下新兴的剪贴板增强工具CleanClip与传统剪贴板,看看到底谁更胜一筹。 1. 剪贴历史管理 传统剪贴板只能存储最后一次…

python-字符排列问题

题目描述 有 n 个字母&#xff0c;列出由该字母组成的字符串的全排列&#xff08;相同的排列只计一次&#xff09;。输入格式 第一行输入是字母个数 n 。 接下来一行输入的是待排列的 n 个字母。输出格式 计算出的 n 个字母的所有不同排列总数。样例输入输出样例输入 4 aacc样例…

JavaScript高级——闭包应用-自定义js模块

定义 JS 模块 具有特定功能的 js 文件将所有的数据和功能都封装在一个函数内部&#xff08;私有的&#xff09;只向外暴露一个包含n个方法的对象或函数模块的使用者&#xff0c;只需要通过模块暴露的对象调用方法来实现对应的功能 例子1: 例子2&#xff1a; 本文分享到这里&am…

软件开发项目,如何应对时间压力?

时间压力是软件开发项目中普遍存在的挑战&#xff0c;妥善应对此问题有助于优化资源配置&#xff0c;控制成本超支&#xff0c;提升团队士气与协作效率&#xff0c;进而增强软件项目的成功率&#xff0c;确保项目按时交付&#xff0c;并提升产品质量和客户满意度。如果无法处理…

『功能项目』事件中心处理怪物死亡【55】

本章项目成果展示 我们打开上一篇54回调函数处理死亡的项目&#xff0c; 本章要做的事情是用事件中心处理怪物死亡后的逻辑 首先打开之前事件中心脚本&#xff08;不做更改&#xff0c;调用即可&#xff09;&#xff1a; using System.Collections.Generic; using UnityEngine…

QT程序的安装包制作教程

在Windows平台上开发完qt c桌面应用程序以后&#xff0c;需要制作一个安装包&#xff0c;方便生产和刻盘交货&#xff0c;本文记录相关流程。 目录 一、安装Qt Installer Framework 二、准备可执行程序 2.1 生成Release程序 2.2 完成依赖库拷贝 三、创建安装包程序 一、…

【MySQL】MySQL和Workbench版本兼容问题

1、安装MySQL WorkBench 最新版本下载&#xff1a;https://dev.mysql.com/downloads/workbench/ 历史版本下载&#xff1a;https://downloads.mysql.com/archives/workbench/ 2、问题描述 本人在Windows下安装了一个旧版本的MySQL&#xff08;5.1&#xff09;&#xff0c;同…

【C++登堂入室】类与对象(上)

目录 一、面向过程和面向对象初步认识 二、类的引入 三、类的定义 四、类的访问限定符及封装 4.1 访问限定符 4.2 封装 五、类的作用域 六、类的实例化 七、类对象模型 7.1如何计算类对象的大小 7.2 类对象的存储方式猜测 7.3 结构体内存对齐规则 八、this指针 …

物联网行业中小型嵌入式文件系统详解以及使用

一 概述 在嵌入式系统使用过程中&#xff0c;为了方便数据的存储&#xff0c;我们加入了串行的外部Flash(SPI通信)。在使用存储的时候&#xff0c;如需要记录一个字符串“奇迹物联Bloom OS”&#xff0c;我们可以把这些文字转化成 ASCII 码&#xff0c;存储在数组中&#xff0c…

Android Studio Menu制作

文章目录 一、创建菜单在Activity上新建onCreateOptionsMenu新建menu目录及资源文件新建Menu一级菜单在Activity上加载Menu测试效果 二、菜单点击事件 一、创建菜单 在Activity上新建onCreateOptionsMenu Overridepublic boolean onCreateOptionsMenu(Menu menu) {return supe…

Vue2电商平台项目 (三) Search模块、面包屑(页面自己跳自己)、排序、分页器!

文章目录 一、Search模块1、Search模块的api2、Vuex保存数据3、组件获取vuex数据并渲染(1)、分析请求数据的数据结构(2)、getters简化数据、渲染页面 4、Search模块根据不同的参数获取数据(1)、 派发actions的操作封装为函数(2)、设置带给服务器的参数(3)、Object.assign整理参…