SpringBoot集成Swagger3.0
一:前言
Swagger 是一个 RESTful API 的开源框架,它的主要目的是帮助开发者设计、构建、文档化和测试 Web API。Swagger 的核心思想是通过定义和描述 API 的规范、结构和交互方式,以提高 API 的可读性、可靠性和易用性,同时降低 API 开发的难度和开发者之间的沟通成本。
这里我采用了Swagger3.0(Open API 3.0)的方式集成到SpringBoot。springfox-boot-start和springfox-swagger2都是基于Swagger2.x的。这里将介绍springdoc-openapi-ui,它是SpringBoot基于Open API 3.0(Swagger3.0)
有兴趣的可以看看第一章介绍,若直接上手看第二章集成Swagger3.0
1:Swagger发展史
Swagger它最初由Tony Tam在2011年创建,并在之后被SmartBear Software公司收购。在过去几年中,Swagger经历了许多重大的更新和变化,
其发展史大概可以分为以下几个阶段:①:Swagger 1.x 阶段(2011-2014年)Swagger最初是一个简单的API文档生成工具,通过对JAX-RS和Jersey注解的支持自动生成API文档,使得API文档的维护变得更加容易。在这个阶段,Swagger还没有完全成熟,只能支持基本的API描述和文档生成。②:Swagger 2.x 阶段(2014-2017年)在Swagger 2.x阶段,Swagger发生了重大变化。它不再仅仅是一个文档生成工具,而是一个完整的API开发和管理平台。Swagger 2.x加入了强大的注解支持,可以描述API的细节信息,如请求参数、返回类型等,以及定义RESTful API的元数据,如API描述、标签等。此外,Swagger 2.x还引入了OpenAPI规范,在API定义方面有了更严格的标准和规则。③:OpenAPI 阶段(2017-至今)(也被称为Swagger 3.x)在2017年,Swagger 2.x的规范成为了Linux基金会旗下的OpenAPI规范。这标志着Swagger从一款工具演变成为了一个开放且标准的API定义框架。OpenAPI规范不仅继承了Swagger 2.x的特性,还提供了更加全面和严格的API定义规范,并且扩展了对非RESTful API的支持随着OpenAPI规范的普及,越来越多的API开发者开始使用Swagger/OpenAPI来开发、测试和文档化他们的RESTful API。所以,随着Linux基金会旗下的OpenAPI收购了Swagger2.x后对其进行了更严格的规范,又进行了各种优化,所以我们也可以称OpenAPI是一个全新的Swagger3.x,因为OpenAPI对其作了更多的优化和规范。
除了上述几个主要阶段之外,还有一些其他重要的事件和版本,如Swagger UI、Swagger Codegen、SwaggerHub等等。
这些工具和服务进一步扩展了Swagger的功能,使其成为了一个更加完整、强大和易于使用的API定义和管理平台。
2:Swagger其它介绍
其实OpenAPI规范(也称为 Swagger 3.x 规范)是一种用于描述RESTful API的标准化格式,它定义了如何描述API的基本信息、结构、参数、响应等方面的规范。OpenAPI规范以机器可读的方式定义了RESTful API的结构和特征,支持自动生成文档、客户端与服务端代码、Mock Server和测试工具等。
OpenAPI规范最初由开发Swagger的团队在2010年推出,从Swagger 2.0开始,Swagger规范被正式更名为OpenAPI规范,并得到了许多社区的支持和贡献。OpenAPI规范采用JSON或YAML格式编写,并支持多种数据类型,可以描述API的基本信息、路径、HTTP方法、参数、响应等各种细节。通过遵循OpenAPI规范,开发者可以快速定义和构建RESTful API,并且可以生成相应的文档和代码来帮助他们更快地开发与测试API。同时,OpenAPI规范还可以促进不同系统之间的交互和集成,因为根据规范定义的API可以被多个客户端程序和服务端程序所理解和使用。
OpenAPI阶段的Swagger也被称为Swagger 3.0。在Swagger 2.0后,Swagger规范正式更名为OpenAPI规范,并且根据OpenAPI规范的版本号进行了更新。因此,Swagger 3.0对应的就是OpenAPI 3.0版本,它是Swagger在OpenAPI阶段推出的一个重要版本。与前几个版本相比,Swagger 3.0更加强调对RESTful API的支持和规范化,提供了更丰富和灵活的定义方式,并且可以用于自动生成文档、客户端代码、服务器代码和测试工具等。
3:SpringFox工具(不推荐)
Springfox是一套可以帮助Java开发者自动生成API文档的工具,它是基于Swagger 2.x基础上开发的。Swagger已经成为了RESTful API文档生态系统的事实标准,而Springfox是一个用于集成Swagger2.x到Spring应用程序中的库。而且Springfox提供了一些注解来描述API接口、参数和返回值,并根据这些信息生成Swagger UI界面,从而方便其他开发人员查看和使用您的API接口。此外,Springfox还支持自动生成API文档和代码片段,简化了开发人员的工作量。除了集成Swagger 2.x,Springfox还提供了一些额外功能,例如自定义Swagger文档、API版本控制、请求验证等等。这些功能使得Springfox可以胜任各种类型和规模的应用程序,同时还可以提高代码质量和开发效率。总之,Springfox是一个非常有用的工具,它可以帮助Java开发者快速、简单地集成Swagger2.x,并为他们的应用程序生成高质量的API文档。无论您开发的是大型企业应用程序还是小型服务,使用Springfox都能够提高团队的生产力和代码质量。
注意:但是随着时间的推移,Swagger2.x终究成为历史,所以我们可以看出springfox-boot-starter的坐标从3.0.0版本(2020年7月14日)开始就一直没有更新;也得注意的是springfox-swagger2坐标和springfox-boot-start是一样的,但springfox-boot-start只有3.0.0版本。这里我就不在使用Swagger2.x版本,具体可以在网上找到许多,因为大部分的网上资料都是Swagger2.x的方式。
4:SpringDoc工具(推荐)
SpringDoc对应坐标是springdoc-openapi-ui,它是一个集成Swagger UI和ReDoc的接口文档生成工具,在使用上与springfox-boot-starter类似,但提供了更为灵活、功能更加强大的工具。其中除了可以生成Swagger UI风格的接口文档,还提供了ReDoc的文档渲染方式,可以自动注入OpenAPI规范的JSON描述文件,支持OAuth2、JWT等认证机制,并且支持全新的OpenAPI 3.0规范。
SpringDoc是基于OpenAPI 3.0规范构建的,因此推荐在Spring Boot 2.4及以上版本中使用springdoc-openapi-ui库来集成Swagger3.x。在这些版本中,springdoc-openapi-ui库已被广泛应用,并且得到了社区的大力支持和推广。而在Spring Boot 2.3及其以下版本,可以使用springfox-boot-starter库来集成Swagger2.x。
SpringDoc是有着更加先进的技术架构和更好的扩展性,使得其逐渐取代了springfox-boot-starter工具包,成为了当前Spring Boot生态中最受欢迎的API文档工具之一。同时springdoc-openapi-ui还拥有更为完善的开发文档和社区支持,从而吸引了越来越多的开发者加入到这个项目中。因此作为一个Spring Boot开发者,如果想要快速、方便地生成符合OpenAPI 3.0规范的接口文档,建议使用springdoc-openapi-ui这个优秀的工具。
二:SpringBoot集成Open API 3.0(Swagger3.0)
具体参考Gitee:https://gitee.com/ant-laddie/hard-working-ant (OpenAPI_3_Demo_Swagger3项目)
我们在SpringBoot中想集成Swagger3.0,一般不选择原生的Maven坐标,而是选择 springdoc-openapi-ui的Maven坐标,它可以很好的和Spring或SpringBoot项目集成;这个坐标也被Spring社区广泛支持和认可,并被认为是集成Swagger UI和OpenAPI规范的一个优秀选择。下面将直接介绍使用。
1:引入Maven依赖
<!-- 导入SpringBoot集成Open API 3.0(Swagger3.0)的坐标 -->
<!-- 这个坐标它提供了一组注解和工具来集成Swagger UI和OpenAPI规范等-->
<dependency><groupId>org.springdoc</groupId><artifactId>springdoc-openapi-ui</artifactId><version>1.7.0</version>
</dependency>说明:上面的坐标内部导入了Swagger3.0的原生依赖(我们只需要在SpringBoot导入springdoc-openapi-ui即可)①:io.swagger.core.v3:swagger-core:2.2.9Swagger Core是Swagger 3.x规范的核心实现,提供了一组Java API,用于生成和处理OpenAPI规范文件。它包括Swagger的核心功能,例如Model、Schema、Parameter、Response等,是构建Swagger API的必要条件。②:io.swagger.core.v3:swagger-annotations:2.2.9Swagger Annotations是一个用于编写Swagger API文档的Java注解库,提供了一组注解,用于描述API元数据。例如,@Operation、@Parameter、@ApiResponse等注解基本包含了OpenAPI规范中的所有元素。③:io.swagger.core.v3:swagger-models:2.2.9Swagger Models是Swagger 3.x规范的Java模型库,提供了一组Java模型类,用于表示OpenAPI规范文件。它包含了OpenAPI规范中的所有数据模型,例如PathItem、Operation、Parameter、Components等。
2:配置SwaggerOpenApiConfig(配置类方式)
注:io.swagger.v3.oas.annotations 是Swagger注解包,而io.swagger.v3.oas.models是Swagger配置类对象方式
其实我们通过配置类的方式创建一个OpenAPI的Bean对象就可以创建Swagger3.0的文档说明,下面我就直创建。
OpenAPI对象是Swagger中的核心类之一,用于描述整个API的结构和元数据。可以理解为一个API文档对象,其中包含了许多元素,如:①:openapi属性:表示使用的 OpenAPI 规范版本(例如 3.0.1)。②:info属性:表示API的基本信息,包括标题、版本号、描述、联系人等。使用Info类来创建这个对象。③:servers属性:表示服务器地址或者URL模板列表。每个URL模板可以包含占位符,这些占位符可以被路径参数或者查询参数替换。使用Server类来创建这个对象。④:paths属性(推荐使用注解方式,不推荐使用配置类配置):表示API的所有路径和操作信息,使用PathItem类来描述每一个路径,使用Operation类来描述操作。⑤:components属性:表示API的组件信息,比如响应模板、请求模板和安全方案等。使用Schema、Response、Parameter、SecurityScheme等类来创建这些对象。⑥:tags属性:表示API的标签信息,用于对相似的操作进行分组。⑦:addServersItem(Server server)方法:向servers属性中添加一个Server对象。⑧:addPaths(String name, PathItem pathItem)方法:向paths属性中添加一个PathItem对象,其中name参数表示路径模板。⑨:addTag(Tag tag)方法:向tags属性中添加一个Tag对象。⑩:setComponents(Components components)方法:设置components属性的值。
import io.swagger.v3.oas.models.OpenAPI;
import io.swagger.v3.oas.models.info.Contact;
import io.swagger.v3.oas.models.info.Info;
import io.swagger.v3.oas.models.info.License;
import org.springframework.boot.SpringBootConfiguration;
import org.springframework.context.annotation.Bean;import java.util.HashMap;/** 这是一个普通的Swagger配置文档,其中不包含API接口的配置(API接口的配置推荐使用注解方式)* @author * @version 1.0**/
@SpringBootConfiguration
public class SwaggerOpenApiConfig {/**** 构建Swagger3.0文档说明* @return 返回 OpenAPI*/@Beanpublic OpenAPI customOpenAPI() {// 联系人信息(contact),构建API的联系人信息,用于描述API开发者的联系信息,包括名称、URL、邮箱等// name:文档的发布者名称 url:文档发布者的网站地址,一般为企业网站 email:文档发布者的电子邮箱Contact contact = new Contact().name("ces") // 作者名称.email("ces@qq.com") // 作者邮箱.url("https://www.cnblogs.com/antLaddie/") // 介绍作者的URL地址.extensions(new HashMap<String, Object>()); // 使用Map配置信息(如key为"name","email","url")// 授权许可信息(license),用于描述API的授权许可信息,包括名称、URL等;假设当前的授权信息为Apache 2.0的开源标准License license = new License().name("Apache 2.0") // 授权名称.url("https://www.apache.org/licenses/LICENSE-2.0.html") // 授权信息.identifier("Apache-2.0") // 标识授权许可.extensions(new HashMap<String, Object>());// 使用Map配置信息(如key为"name","url","identifier")//创建Api帮助文档的描述信息、联系人信息(contact)、授权许可信息(license)Info info = new Info().title("Swagger3.0 (Open API) 框架学习示例文档") // Api接口文档标题(必填).description("学习Swagger框架而用来定义测试的文档") // Api接口文档描述.version("1.2.1") // Api接口版本.termsOfService("https://example.com/") // Api接口的服务条款地址.license(license) // 设置联系人信息.contact(contact); // 授权许可信息// 返回信息return new OpenAPI().openapi("3.0.1") // Open API 3.0.1(默认).info(info); // 配置Swagger3.0描述信息}
}
3:配置SwaggerOpenApiConfig(注解方式)
上面我们使用了Java代码创建Bean的方式,其实这种写起来感觉还行,但是在使用了注解方式是很舒服的,下面就简单说明:
定义Swagger3.0配置信息注解:@OpenAPIDefinition (具体参考 io.swagger.v3.oas.annotations)
注意:这个注解全局只能配置一个,主要配置文档信息和安全配置说明:用于描述整个API的元信息和全局属性,可以定义和描述,包括API版本、基本信息、服务器信息、安全方案等常用属性:①:info:用于描述 API 基本信息的对象,包括标题、版本号、描述等属性;②:servers:用于描述 API 服务的 URL 和配置信息的数组;③:security:用于描述 API 安全方案的数组,其中每个安全方案包含多个安全需求;④:tags:用于描述 API 标签的数组,每个标签包含名称、描述等属性;⑤:externalDocs:用于描述外部文档链接的对象,包含描述和 URL 两个属性。
import io.swagger.v3.oas.annotations.ExternalDocumentation;
import io.swagger.v3.oas.annotations.OpenAPIDefinition;
import io.swagger.v3.oas.annotations.info.Contact;
import io.swagger.v3.oas.annotations.info.Info;
import io.swagger.v3.oas.annotations.info.License;
import io.swagger.v3.oas.annotations.servers.Server;
import org.springframework.boot.SpringBootConfiguration;/*** @author * @version 1.0**/
@SpringBootConfiguration
@OpenAPIDefinition(// ## API的基本信息,包括标题、版本号、描述、联系人等info = @Info(title = "Swagger3.0 (Open API) 框架学习示例文档", // Api接口文档标题(必填)description = "学习Swagger框架而用来定义测试的文档", // Api接口文档描述version = "1.2.1", // Api接口版本termsOfService = "https://example.com/", // Api接口的服务条款地址contact = @Contact(name = "蚂蚁小哥", // 作者名称email = "xiaofeng@qq.com", // 作者邮箱url = "https://www.cnblogs.com/antLaddie/" // 介绍作者的URL地址),license = @License( // 设置联系人信息name = "Apache 2.0", // 授权名称url = "https://www.apache.org/licenses/LICENSE-2.0.html" // 授权信息)),// ## 表示服务器地址或者URL模板列表,多个服务地址随时切换(只不过是有多台IP有当前的服务API)servers = {@Server(url = "http://192.168.2.235/demo/", description = "本地服务器一服务"),@Server(url = "http://192.168.2.236/demo/", description = "本地服务器二服务"),},externalDocs = @ExternalDocumentation(description = "更多内容请查看该链接", url = "xxx"))
public class SwaggerOpenApiConfig {
}
4:配置API接口信息(注解,重要)
说了这么久,Swagger3.0的全局基本信息配置是处理好了,接下来就是配置接口了,因为我之前写了Controller代码,但是没有接口配置信息,这里我就使用Swagger的方式进行一个简单的配置。
示例代码,不是太明白属性的可以看下面属性介绍
// 响应对象模型定义
@Data
@AllArgsConstructor
@Schema(description = "响应返回数据对象")
public class AjaxResult {@Schema(title = "code",description = "响应码",format = "int32",requiredMode = Schema.RequiredMode.REQUIRED)private Integer code;@Schema(title = "msg",description = "响应信息",accessMode = Schema.AccessMode.READ_ONLY,example = "成功或失败",requiredMode = Schema.RequiredMode.REQUIRED)private String msg;@Schema(title = "data", description = "响应数据", accessMode = Schema.AccessMode.READ_ONLY)private Object data;
}
// 模型定义示例:
@Data
@AllArgsConstructor
@Schema(title = "学生模型VO", description = "响应视图学生模型VO")
public class StudentVO {@Schema(name = "学生ID", description = "学生ID属性", format = "int64", example = "1")private Long id; // 学生ID@Schema(name = "学生姓名", description = "学生姓名属性", example = "jack")private String name; // 学生姓名@Schema(name = "学生年龄", description = "学生年龄属性", format = "int32", example = "24")private Integer age; // 学生年龄@Schema(name = "学生地址", description = "学生地址属性", example = "安徽合肥")private String address; // 学生地址@Schema(name = "学生分数", description = "学生分数属性", format = "double", example = "55.50")private Double fraction; // 学生分数@Schema(name = "学生爱好", description = "学生爱好属性(List类型)",type = "array", example = "[\"玩\", \"写字\"]")private List<String> likes; // 学生爱好
}
// 接口定义
@RestController
@RequestMapping("/student")
@Tag(name = "StudentControllerAPI",description = "学生控制器接口",externalDocs = @ExternalDocumentation(description = "这是一个接口文档介绍",url = "https://www.cnblogs.com/antLaddie/"))
public class StudentController {/**** 根据ID查询学生信息(单条)* @param id 学生id* @return 返回一条数据*/@Operation(summary = "根据Id查询学生信息",description = "根据ID查询学生信息,并返回响应结果信息",parameters = {@Parameter(name = "id", description = "学生ID", required = true, example = "1")},responses = {@ApiResponse(responseCode = "200",description = "响应成功",content = @Content(mediaType = "application/json",schema = @Schema(title = "AjaxResul和StudentVO组合模型",description = "返回实体,AjaxResult内data为StudentVO模型",anyOf = {AjaxResult.class, StudentVO.class}))),@ApiResponse(responseCode = "500",description = "响应失败",content = @Content(mediaType = "application/json",schema = @Schema(title = "AjaxResul模型",description = "返回实体,AjaxResult内data为空",implementation = AjaxResult.class)))})@GetMapping("/findOne/{id}")public AjaxResult findOneStudent(@PathVariable(value = "id") Long id) {//模拟学生数据List<String> likes = Arrays.asList("抓鱼", "爬山", "写字");StudentVO studentVO = new StudentVO(id, "张三", 22, "安徽六安", 93.5, likes);return new AjaxResult(200, "成功", studentVO);}/**** 查询全部学生数据* @return 返回d条数据*/@Operation(summary = "查询全部学生数据",description = "查询学生信息,并返回响应结果信息",parameters = {},deprecated = true,responses = {@ApiResponse(responseCode = "200",description = "响应成功",content = @Content(mediaType = "application/json",schema = @Schema(title = "AjaxResul和StudentVO组合模型",description = "返回实体,AjaxResult内data为" +"StudentVO模型(并且StudentVO为集合)",anyOf = {AjaxResult.class, StudentVO.class})))})@GetMapping("/findAll")public AjaxResult findAllStudent() {//模拟学生数据List<String> likes = Arrays.asList("抓鱼", "爬山", "写字");StudentVO student1 = new StudentVO(1L, "张三", 22, "安徽六安", 93.5, likes);StudentVO student2 = new StudentVO(2L, "李四", 24, "安徽合肥", 99.5, likes);return new AjaxResult(200, "成功", Arrays.asList(student1, student2));}/**** 学生添加接口* @param studentDTO 学生DTO信息* @return 成功信息*/@Operation(summary = "学生添加接口",description = "学生添加接口",parameters = {},requestBody = @io.swagger.v3.oas.annotations.parameters.RequestBody(description = "学生信息DTO",required = true,content = {@Content(mediaType = "application/json",schema = @Schema(implementation = StudentDTO.class))}),responses = {@ApiResponse(responseCode = "200",description = "响应成功",content = @Content(mediaType = "application/json",schema = @Schema(title = "AjaxResul模型",description = "返回实体AjaxResult,并且Data为null",implementation = AjaxResult.class)))})@PostMapping("/saveStudent")public AjaxResult saveStudent(@RequestBody StudentDTO studentDTO) {System.out.println("成功添加数据:" + studentDTO);return new AjaxResult(200, "成功", null);} ........ 省略}
配置文档标题及归类,就是在Controller上配置。
注解:@Tag 可以用于对接口进行分类和归类,便于开发人员组织和管理 API 文档
具体属性:
①:name:表示标签的名称,必填属性,也得注意多个Controller上的name不要写一样的,这样就会把它们归类在一起。
②:description:表示标签的描述信息,非必填属性。
③:externalDocs:用于指定URL地址文档信息来追加描述接口的信息。非必填属性。
示例:
@Tag(
name = “StudentControllerAPI”,
description = “学生控制器接口”,
externalDocs = @ExternalDocumentation(
description = “这是一个接口文档介绍”,
url = “https://www.cnblogs.com/antLaddie/”))
配置文档下的每一个接口信息,就是Controller里的每一个RequestMapping
注解:@Operation用于对API操作(即方法)进行描述和标记。就是我们熟知的Controller下的一个个请求的方法上。具体可以参考 io.swagger.v3.oas.annotations。具体属性:①:summary:用于简要描述API操作的概要。②:description:用于详细描述API操作的描述信息。③:parameters:用于指定API操作的参数列表,包括路径参数、请求参数、请求头部等。可以使用@Parameter注解进一步定义参数。④:operationId:用于指定API操作的唯一标识符,可以用于生成客户端代码或文档等。说明:第三方工具使用operationId来唯一标识此操作。(具体我也没用过)⑤:requestBody:用于定义API操作的请求体,可以使用@RequestBody注解进一步定义请求体。说明:这里的@RequestBody注解是@io.swagger.v3.oas.annotations.parameters.RequestBody包里的⑥:responses:用于定义 API 操作的响应列表,包括成功响应和错误响应。可以使用@ApiResponse注解进一步定义响应。⑦:security:用于对API操作进行安全控制,可以使用@SecurityRequirement注解进一步定义安全需求。(后面说)⑧:deprecated:表示该API操作已经过时或不推荐使用。@Operation(summary = "根据Id查询学生信息",description = "根据ID查询学生信息,并返回响应结果信息",parameters = {@Parameter(name = "id", description = "学生ID", required = true, example = "1")},responses = {@ApiResponse(responseCode = "200",description = "响应成功",content = @Content(mediaType = "application/json",schema = @Schema(title = "AjaxResul和StudentVO组合模型",description = "返回实体,AjaxResult内data为StudentVO模型",anyOf = {AjaxResult.class, StudentVO.class})))})
配置请求接口参数信息
注解:@Parameter用于描述HTTP请求的参数信息,它是一个Parameter[]类型的数组,每个元素表示一个请求参数;具体参考:io.swagger.v3.oas.annotations;它是一个注解,和Parameter类一样,只不过一个是注解一个是类的方式①:name:参数名称。②:in:参数位置,可以是 query、header、path、cookie 等。③:description:参数描述。④:required:参数是否必须,默认为 false。⑤:deprecated:参数是否已过时,默认为 false。⑥:allowEmptyValue:是否允许空值,默认为false。⑦:style:参数的序列化风格,可以是 "matrix"、"label"、"form"、"simple"、"spaceDelimited"、"pipeDelimited"、"deepObject";⑧:explode:当参数值是对象或数组时,是否将其展开成多个参数,默认为 false。⑨:schema:参数类型和格式的定义,通常使用@Schema注解。(下面介绍)⑩:example:参数值的示例;示例:parameters = {@Parameter(name = "id", in = ParameterIn.PATH, description = "学生ID",required = true, example = "1")},
配置具体的实体模型信息
注解:@Schema 是用于描述数据模型的基本信息和属性,具体可以参考“io.swagger.v3.oas.annotations.media”具体属性:①:description:用于描述该类或属性的作用。②:name:指定属性名。该属性只对属性有效,对类无效。③:title:用于显示在生成的文档中的标题。④:requiredMode:用于指定该属性是否必填项。枚举Schema.RequiredMode内可选值如下:默认AUTO:可有可无;REQUIRED:必须存在此字段(会加红色*);NOT_REQUIRED:不需要存在此字段⑤:accessMode:用于指定该属性的访问方式。包括AccessMode.READ_ONLY(只读)、AccessMode.WRITE_ONLY(只写)、AccessMode.READ_WRITE(读写)⑥:format:用于指定该属性的数据格式。例如:日期格式、时间格式、数字格式。⑦:example:为当前的属性创建一个示例的值,后期测试可以使用此值。⑧:deprecated:用于指定该属性是否为已过时的属性,默认为false。⑨:defaultValue:用于指定该属性的默认值。⑩:implementation:用于显示为该类或属性引入具体的实体路径,这代表当前指定的类或者属性将参考引入的实体。就是说有个实体类,这个类里面有个teacher属性,这时里面的teacher属性可以指定具体的实体类,如下:public class Student {...@Schema(description = "老师信息",implementation = Teacher.class)private Teacher teacher;...}其它属性:①:type:用于指定数据类型(Data Type)或者元素类型(Element Type)基本类型:取值为相应的 Java 类型名,例如 int、long、float、double、boolean 等。包装类型:与基本类型相同,取值为相应的Java包装类型名,例如Integer、Long、Float、Double、Boolean等。字符串类型:取值为string。数组类型:取值为 array。对于数组类型,还可以使用 schema 属性指定其元素类型的 Schema 信息。对象类型:不用指定type,可以通过implementation属性引入。枚举类型:取值为enum。对于枚举类型,还需要使用enumAsRef属性指定是否将其定义为一个独立的引用类型。其它类型:不用指定type,可以通过implementation属性引入。@Schema注解:提供了四个属性来描述复杂类型,分别是allOf、anyOf、oneOf和not。这四个属性可以用于组合不同的JSON Schema以描述一个复杂类型,具体如下:①:allOf: 表示当前schema是多个其它schema的并集。例如,如果一个Java类型同时实现了两个接口,那么可以使用allOf来表示这个Java类型继承了这两个接口的所有属性和方法。②:anyOf: 表示当前schema可以匹配其中任意一个schema,其本身也是一个组合体,可以嵌套使用。例如,一个返回类型可能是多个Java类型中的任意一个,可以使用anyOf来描述这种情况。③:oneOf: 表示当前schema只能匹配其中一个schema,其本身也是一个组合体,可以嵌套使用。例如,一个Java类型只能是多个子类型中的任意一个,可以使用oneOf来描述这种情况。④:not: 表示当前Schema不能匹配某个schema。例如,一个Java类型不能是某个子类型,可以使用not来描述这种情况。但是总感觉这个Swagger无法满足我特定要求的实体,具体解决如下:比如我现在有个AjaxResult类(code,msg,data),其中data为Object或其它类型,这时我返回的数据里data为其它类型的实体,所以我这里不理解如何返回的实体中,通过点击data而显示另外实体,我只能通过anyOf方式来实现(加上注解)@ApiResponse(responseCode = "200",description = "响应成功",content = @Content(mediaType = "application/json",schema = @Schema(description = "返回实体,AjaxResult内data为StudentVO模型",anyOf = {AjaxResult.class, StudentVO.class})))
5:配置API接口信息(定义类方式,不推荐)
上面介绍了使用注解的方式完成接口的说明,这里我来说说定义类的方式来完成接口的定义,其实这种方式不推荐,写起来繁琐麻烦,后期改起来也乱,但是还是说下,下面就是具体的代码信息
/*** 老师接口描述** @author * @version 1.0**/
public class InterfaceDescriptionConfig {/**** get方式保存老师信息接口* @return PathItem*/public static PathItem addTeacher() {//=====================创建字段描述信息(老师类描述)如:TeacherDTO=====================Schema id = new IntegerSchema().format("int64").description("老师ID");Schema name = new StringSchema().minLength(2).maxLength(5).example("张三").description("老师姓名");Schema age = new IntegerSchema().format("int32").maximum(new BigDecimal("99")).minimum(new BigDecimal("1")).example("23").description("老师年龄");Schema birthday = new DateSchema().format("date").example("2023-12-12").description("老师生日");Schema address = new StringSchema().minLength(2).maxLength(9).example("安徽省").description("老师地址");Schema salary = new NumberSchema().format("bigDecimal").maximum(new BigDecimal("99999.99")).minimum(new BigDecimal("100.00")).example("6500.50").description("老师工资");Schema fraction = new NumberSchema().format("double").maximum(new BigDecimal("99.99")).minimum(new BigDecimal("10.00")).example("25.3").description("老师评分");Schema likes = new ArraySchema().minItems(1).maxItems(10).description("这是一个爱好数组");Schema isHeadmaster = new BooleanSchema().example(true).description("是否是班主任");Schema schema = new ObjectSchema().description("老师对象属性").addProperty("id", id).addProperty("name", name).addProperty("age", age).addProperty("birthday", birthday).addProperty("address", address).addProperty("salary", salary).addProperty("fraction", fraction).addProperty("likes", likes).addProperty("isHeadmaster", isHeadmaster);//=====================响应字段描述信息(返回类描述)如:AjaxResult=====================Schema resultSchema = new ObjectSchema().description("响应信息对象").addProperty("code", new IntegerSchema().example("200").description("响应码")).addProperty("msg", new StringSchema().example("成功").description("响应信息")).addProperty("data", schema);//设置响应头信息,可以设置系统响应头,也可以设置自定义响应头,具体声明,前端好获取指定响应头信息HashMap<String, Header> headers = new HashMap<>();headers.put("my-header1", new Header().description("测试响应头1").schema(new StringSchema()));headers.put("my-header2", new Header().description("测试响应头2").schema(new StringSchema()));headers.put("my-header3", new Header().description("测试响应头3").schema(new StringSchema()));// 设置响应信息ApiResponses apiResponses = new ApiResponses().addApiResponse("200", new ApiResponse().description("响应成功信息").headers(headers).content(new Content().addMediaType("application/json",new MediaType().schema(resultSchema)))).addApiResponse("500", new ApiResponse().description("响应失败"));// 设置请求信息RequestBody requestBody = new RequestBody().content(new Content().addMediaType("application/json",new MediaType().schema(schema)));// 设置请求URL后缀参数信息(可以添加多个) 接口描述List<Parameter> parameters = new ArrayList<>();Parameter sign = new Parameter().name("sign") // 设置参数名称.description("URL参数标记信息") // 设置描述.required(false) // 是否必传.in("path") // 参数信息参数位置(当前在URL路径后).schema(new StringSchema()) // 参数类型.example("tx117839"); // 示例数据parameters.add(sign);// 设置当前接口描述信息Operation operation1 = new Operation().operationId("addTeacher").description("这是一个添加老师信息的接口").requestBody(requestBody).parameters(parameters).responses(apiResponses);// 设置接口路径信息及请求方式(这里我设置了一个post请求的接口)return new PathItem().post(operation1).description("POST请求");}
}接口及模型的描述(使用定义类的方式)
import io.swagger.v3.oas.models.OpenAPI;
import io.swagger.v3.oas.models.Paths;
import org.springframework.boot.SpringBootConfiguration;
import org.springframework.context.annotation.Bean;/*** @author * @version 1.0**/
@SpringBootConfiguration
public class SwaggerOpenApiConfig1 {/**** 构建Swagger3.0文档说明* @return 返回 OpenAPI*/@Beanpublic OpenAPI customOpenAPI() {// 配置Info信息 ... //通过Paths可以配置多组接口信息(Paths接收PathItem,这里的每个PathItem我抽取方式出去了)Paths paths = new Paths();paths.put("根据传入的老师信息进行数据保存", InterfaceDescriptionConfig.addTeacher());// 返回信息return new OpenAPI().openapi("3.0.1") // Open API 3.0.1(默认).paths(paths).info(null); // 配置Swagger3.0描述信息}
}接口信息的绑定到Swagger中
6:权限认证方式
其实我们的接口都是有权限校验方式的,每个接口在请求时都是包含校验,如我们常见的JWT校验,我们访问每个接口都需要携带Token信息,下面我就简单说说校验认证的方式描述。
注解权限设置:@SecurityScheme (具体参考io.swagger.v3.oas.annotations.security)说明:用于定义API的安全方案。通过使用@SecurityScheme注解,我们可以为API定义多种安全方案,并指定每种方案的相关属性,例如认证类型、授权URL、令牌URL、作用域等。常用属性:①:name:安全方案的名称;②:type:认证类型,具体包含如下:SecuritySchemeType.API_KEY(API密钥)、SecuritySchemeType.HTTP(HTTP认证)、SecuritySchemeType.OAUTH2(OAuth2.0 认证)等;③:description:安全方案的描述信息;④:in:仅在使用API密钥认证时适用,表示API密钥的位置,包括如下:ApiKeyLocation.HEADER(HTTP 头部)、ApiKeyLocation.COOKIE(Cookie)等⑤:scheme:仅在使用HTTP认证时适用,表示认证方案,例如HTTP Authentication Scheme.Basic(Basic 认证);防止客户端需要在请求头部中添加一个包含用户名和密码的 Base64 编码字符串,并以 "Basic " 开头,如:Authorization: Basic YWRtaW46MTIzNDU2⑥:bearerFormat:仅在使用 Bearer Token 认证时适用,表示 Bearer Token 的格式;⑦:flows:仅在使用OAuth2.0认证时适用,表示OAuth2.0的认证流程,包括@OAuthFlows.authorizationCode、@OAuthFlows.clientCredentials、@OAuthFlows.password 和 @OAuthFlows.implicit等。示例:(可以在我们自定义的SwaggerOpenApiConfig内设置权限认证)@SecurityScheme(name = "JWT-test", // 认证方案名称type = SecuritySchemeType.HTTP, // 认证类型,当前为http认证description = "这是一个认证的描述详细", // 描述信息in = SecuritySchemeIn.HEADER, // 代表在http请求头部scheme = "bearer", // 认证方案,如:Authorization: bearer token信息bearerFormat = "JWT") // 表示使用 JWT 格式作为 Bearer Token 的格式
比如我添加了一个名称为”JWT-test“的验证方式,使用方式存在2种,一种是设置全部文档使用这种验证,另一种是某个接口使用此种校验方式,具体使用如下:
当前在自定义的SwaggerOpenApiConfig类上面设置了两种权限校验方式,如下:
@SecurityScheme(name = "JWT-test", // 认证方案名称type = SecuritySchemeType.HTTP, // 认证类型,当前为http认证description = "这是一个认证的描述详细", // 描述信息in = SecuritySchemeIn.HEADER, // 代表在http请求头部scheme = "bearer", // 认证方案,如:Authorization: bearer token信息bearerFormat = "JWT") // 表示使用 JWT 格式作为 Bearer Token 的格式
@SecurityScheme(name = "X-API-KEY",type = SecuritySchemeType.APIKEY,description = "这是一个认证的描述详细",in = SecuritySchemeIn.HEADER,scheme = "bearer")设置全部接口描述都有指定的一种校验方式:在@OpenAPIDefinition注解里的security属性设置校验方式@OpenAPIDefinition( ....security = @SecurityRequirement(name = "JWT-test"))
设置指定接口描述有指定的一种校验方式:在@Operation注解里的security属性设置校验方式@Operation( ....security = @SecurityRequirement(name = "JWT-test"))
相关文章:
SpringBoot集成Swagger3.0
一:前言 Swagger 是一个 RESTful API 的开源框架,它的主要目的是帮助开发者设计、构建、文档化和测试 Web API。Swagger 的核心思想是通过定义和描述 API 的规范、结构和交互方式,以提高 API 的可读性、可靠性和易用性,同时降…...
计算机网络-第5章 运输层(1)
主要内容:进程之间的通信与端口、UDP协议、TCP协议、可靠传输原理(停止等待协议、ARQ协议)、TCP报文首部、TCP三大题:滑动窗口、流量控制、拥塞控制机制 5.1 运输层协议概述 运输层向它上面的应用层提供通信服务,真正…...
性能优化-卡牌项目渲染优化
优化的方向 CPU 影响帧率 GPU 影响帧率 内存 超了会崩 显存 显存超了画面会异常,甚至可能导致游戏崩溃 带宽 影响耗电 分辨率 设备性能不行又要求流畅,降低目标渲染分辨率,立竿见影,但是会牺牲画质 场景 1 使用烘焙…...
STM32FreeRTOS任务通知(STM32cube高效开发)
文章目录 一、任务通知(一)任务通知概述1、任务通知可模拟队列和信号量2、任务通知优势和局限性 (二) 任务通知函数1、xTaskNotify()发送通知值不返回先前通知值的函数2、xTaskNotifyFromISR()发送通知函数ISR版本3、x…...
基于element-plus的Dialog选择控件
翻看之前工程师写的vue2的代码,很多都是复制、粘贴,也真是搞不懂,明明可以写一个控件,不就可以重复使用。很多前端总喜欢element搞一下,ant-design也搞一下,有啥意义,控件也不是自己写的&#x…...
手把手教使用静默 搭建Oracle 19c 一主一备ADG集群
一、环境搭建 主机IPora19192.168.134.239ora19std192.168.134.240 1.配置yum源 1.配置网络yum源 1.删除redhat7.0系统自带的yum软件包; rpm -qa|grep yum >oldyum.pkg 备份原信息rpm -qa|grep yum|xargs rpm -e --nodeps 不检查依赖,直接删除…...
使用协程库httpx并发请求
httpx和aiohttp都是比较常用的异步请求库,当然requests多线程或requestsgevent也是不错的选择。 一个使用httpx进行并发请求的脚本如下: import functools import sys import timeimport anyio import httpxasync def fetch(client, results, index) -…...
js的同步异步
JavaScript(JS)是一门单线程的编程语言,这意味着它一次只能处理一个任务。然而,JS 支持同步和异步操作。 同步操作是指代码按照顺序执行,每个操作必须在前一个操作完成后才能进行。这意味着当一个操作在执行时&#x…...
C# MG.CamCtrl 工业相机库(开源) 海康 大恒
C# MG.CamCtrl 相机库(开源) 海康 大恒 介绍工厂模式创建实例选取对应SN号的相机,初始化启动相机取图注销相机参数设置/获取接口 介绍 c# 相机库,含海康、大恒品牌2D相机的常用功能。 底层采用回调信号量模式封装 ,最…...
【Redis】redis的基本使用
📝个人主页:五敷有你 🔥系列专栏:Redis ⛺️稳中求进,晒太阳 Redis的概述 为什么要有redis? redis是数据库,mysql也是数据库,redis做缓存的意义就是为了减轻数据库压力 数据库为什么…...
植物病害识别:YOLO水稻病害识别数据集(3000多张,3个类别,yolo标注)
YOLO水稻病害识别数据集,包含细菌性枯萎病,水稻瘟疫,褐斑病3个常见病害类别,共3000多张图像,yolo标注完整,可直接训练。 适用于CV项目,毕设,科研,实验等 需要此数据集或…...
Java实现Tron(波场)区块链的开发实践(三)波场链水龙头、WEB3测试实战
上一节我们具体讲到Java实现Tron波场链的逻辑代码实现。 这一节我们通过部署和开发好的代码,针对测试链进行自测开发,准备测试环境。 1. 创建离线地址 首先我们需要一个离线地址,我们不需要在线进行创建,直接可以通过第一节的离…...
010-$nextTick
$nextTick 1、问题2、$nextTick3、应用场景 1、问题 Vue 实现响应式,在 data 更新后,一定时间内,没有继续操作DOM,然后会触发浏览器渲染引擎去更新DOM,更新DOM也是需要时间的,所以 data 更新引起的 DOM更新…...
[IAGC] Kafka消费者组的负载均衡策略
在Apache Kafka中,负载均衡是通过将主题的每个分区分配给消费者组中的一个消费者来实现的。Kafka的负载均衡算法会尽可能平均地将分区分配给每个消费者。 文章目录 分配策略Kafka的重新平衡扩展性参考资源 分配策略 在Kafka中,有两种内置的分区分配策略…...
2024年会声会影 迎接来了七大新功能
我喜欢Corel VideoStudio 会声会影2024旗舰版,因为它使用起来很有趣。它很容易使用,但仍然给你很多功能和力量。VideoStudio让我与世界分享我的想法!“这个产品的功能非常多,我几乎没有触及它的表面,我可以做大量的编辑…...
AIGC、3D模型、轻量化、格式转换、可视化、数字孪生引擎等(老子云三维模型可视化优化服务平台)
老子云概述 老子云3D可视化快速开发平台,集云压缩、云烘焙、云存储云展示于一体,使3D模型资源自动输出至移动端PC端、Web端,能在多设备、全平台进行展示和交互,是全球领先、自主可控的自动化3D云引擎。 平台架构 平台特性 基于 H…...
JMM(Java Memory Model)内存模型
Java内存模型,规范了计算机内存与java虚拟机之间的协调工作,即规定了 将java 虚拟机中的变量存储到内存中和从内从中取出来的内存细节。 Java内存模型中规定了所有的变量都存储在内存中,每条线程还有自己的工作内存,线程对变量的…...
.NET 简介:跨平台、开源、高性能的开发平台
.NET 简介 .NET 是微软开发的一个免费、开源、跨平台的开发人员平台,用于构建各种类型的应用程序。它可以运行使用多种语言编写的程序,其中 C# 是最常用的语言。.NET 依赖于许多大规模应用在生产中使用的高性能运行时。 .NET 平台具有以下特点…...
m序列生成器
function [m] mserial_generator(tap_set) % m序列产生器 % 输出为m序列,未进行极性变换。 L 2^(length(tap_set)-1)-1; x [zeros(1,(length(tap_set)-2)) 1]; for i 1:1:Lm(i)x(end);for j 1:1:length(tap_set)-1sum_vector(j)tap_set(j1)*x(j);endsum_x mod…...
go的数据类型看这一篇就够了
目录 一:类型分类 二:介绍 一:类型分类 go的数据类型包含11种,可以分为以下四类。 1:基础类型:布尔,数字和字符串: 2:复合类型:数组和结构体 3:引用类型: 指针,channel通道,切片,map字典,函数 4:接口类型 二:介绍 1:布尔 一个布尔类型的值只有两种:tr…...
【Go】3、Go语言进阶与依赖管理
前言 本系列文章参考自稀土掘金上的 【字节内部课】公开课,做自我学习总结整理。 Go语言并发编程 Go语言原生支持并发编程,它的核心机制是 Goroutine 协程、Channel 通道,并基于CSP(Communicating Sequential Processes࿰…...
VTK如何让部分单位不可见
最近遇到一个需求,需要让一个vtkDataSet中的部分单元不可见,查阅了一些资料大概有以下几种方式 1.通过颜色映射表来进行,是最正规的做法 vtkNew<vtkLookupTable> lut; //值为0不显示,主要是最后一个参数,透明度…...
关于 WASM:1. WASM 基础原理
一、WASM 简介 1.1 WebAssembly 是什么? WebAssembly(WASM) 是一种能在现代浏览器中高效运行的二进制指令格式,它不是传统的编程语言,而是一种 低级字节码格式,可由高级语言(如 C、C、Rust&am…...
k8s业务程序联调工具-KtConnect
概述 原理 工具作用是建立了一个从本地到集群的单向VPN,根据VPN原理,打通两个内网必然需要借助一个公共中继节点,ktconnect工具巧妙的利用k8s原生的portforward能力,简化了建立连接的过程,apiserver间接起到了中继节…...
(转)什么是DockerCompose?它有什么作用?
一、什么是DockerCompose? DockerCompose可以基于Compose文件帮我们快速的部署分布式应用,而无需手动一个个创建和运行容器。 Compose文件是一个文本文件,通过指令定义集群中的每个容器如何运行。 DockerCompose就是把DockerFile转换成指令去运行。 …...
【Oracle】分区表
个人主页:Guiat 归属专栏:Oracle 文章目录 1. 分区表基础概述1.1 分区表的概念与优势1.2 分区类型概览1.3 分区表的工作原理 2. 范围分区 (RANGE Partitioning)2.1 基础范围分区2.1.1 按日期范围分区2.1.2 按数值范围分区 2.2 间隔分区 (INTERVAL Partit…...
【开发技术】.Net使用FFmpeg视频特定帧上绘制内容
目录 一、目的 二、解决方案 2.1 什么是FFmpeg 2.2 FFmpeg主要功能 2.3 使用Xabe.FFmpeg调用FFmpeg功能 2.4 使用 FFmpeg 的 drawbox 滤镜来绘制 ROI 三、总结 一、目的 当前市场上有很多目标检测智能识别的相关算法,当前调用一个医疗行业的AI识别算法后返回…...
OPENCV形态学基础之二腐蚀
一.腐蚀的原理 (图1) 数学表达式:dst(x,y) erode(src(x,y)) min(x,y)src(xx,yy) 腐蚀也是图像形态学的基本功能之一,腐蚀跟膨胀属于反向操作,膨胀是把图像图像变大,而腐蚀就是把图像变小。腐蚀后的图像变小变暗淡。 腐蚀…...
算法笔记2
1.字符串拼接最好用StringBuilder,不用String 2.创建List<>类型的数组并创建内存 List arr[] new ArrayList[26]; Arrays.setAll(arr, i -> new ArrayList<>()); 3.去掉首尾空格...
CSS设置元素的宽度根据其内容自动调整
width: fit-content 是 CSS 中的一个属性值,用于设置元素的宽度根据其内容自动调整,确保宽度刚好容纳内容而不会超出。 效果对比 默认情况(width: auto): 块级元素(如 <div>)会占满父容器…...
