SpringBoot整合Swagger3生成接口文档

一:前言

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)

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)

我们在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 Anhui OuYang* @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("蚂蚁小哥")                             // 作者名称.email("xiaofeng@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 Anhui OuYang* @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 Anhui OuYang* @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 Anhui OuYang* @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集成Open API3.0具体运行效果

访问:http://localhost:8888/demo/swagger-ui/index.html

总览

在这里插入图片描述
学生Controller根据ID查询学生界面

在这里插入图片描述
模型定义信息

在这里插入图片描述
权限认证(这里我配置两个在Swagger配置类上)

在这里插入图片描述

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

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

相关文章

深度图转点云

一、理论分析 二、其他分析 1、相机内参 相机内参主要是四个参数fx,fy,u0,v0。要明白相机内参就是相机内部参数&#xff0c;是参考像素坐标系而言&#xff0c;有了这个前提&#xff0c;这四个参数也就很好理解了。 &#xff08;1&#xff09;首先&#xff0c;。其中F是相机的…

Oracle中的 plsql语法

01-plsql 为什么要plsql 复杂的业务逻辑 可以使用 编程语言实现 sql无法实现 plsql也可以实现复杂的业务逻辑 为不直接使用编程语言 而是学习plsql plsql会比直接使用 编程语言 速度更快 基本语法&#xff1a; [declare --声明变量 变量名 变量类型 ] begin --代码逻辑 …

Springboot Gateway 报错Failed to resolve “bogon”的原因及解决办法

一、问题出现原因及初步分析 今天遇到一个奇怪的错误&#xff0c;一个一直正确运行的微服务后台&#xff0c;突然无法访问&#xff0c;如何重启都会报错。 想到近期有人在服务器上安装过其它服务&#xff0c;因此&#xff0c;考虑可能是配置问题&#xff0c;可配置问题修复后…

1.基于Springboot对SpringEvent初步封装

一&#xff1a;前置知识 Spring Event是Spring框架提供的一种事件机制&#xff0c;用于处理组件之间的通信。在复杂的系统中&#xff0c;模块或组件之间的通信是必不可少的。Spring Event可以用于以下场景&#xff1a; 1.系统间解耦&#xff1a;模块或组件之间通过事件进行通…

账号安全基本措施1

一、系统账号清理 1.1 将用户设置为无法登录 useradd -s /sbin/nologin lisi shell类型设置为/sbin/nologin用户将无法使用bash或其他shell来登录系统。 1.2 锁定用户。passwd -l 用户名 正常情况下是可以送普通用户切换到其他普通用户的 当锁定密码后passwd -l lisi就用普…

LeetCode:组合求和III之回溯法

题目 题目链接 找出所有相加之和为 n 的 k 个数的组合&#xff0c;且满足下列条件&#xff1a;只使用数字1到9 每个数字 最多使用一次 返回 所有可能的有效组合的列表 。该列表不能包含相同的组合两次&#xff0c;组合可以以任何顺序返回。题目图解 ** ** cpp代码 class …

AI预测体彩排列3第2套算法实战化测试第1弹2024年4月22日第1次测试

从今天开始&#xff0c;开始新一轮的测试&#xff0c;本轮测试&#xff0c;以6码为基础&#xff0c;同步测试杀号情况&#xff0c;争取杀至4-5码。经过计算&#xff0c;假如5码命中&#xff0c;即每期125注&#xff0c;投入250元&#xff0c;十期共计2500元&#xff0c;则命中率…

牛客NC233 加起来和为目标值的组合(四)【中等 DFS C++、Java、Go、PHP】

题目 题目链接&#xff1a; https://www.nowcoder.com/practice/7a64b6a6cf2e4e88a0a73af0a967a82b 解法 dfs参考答案C class Solution {public:/*** 代码中的类名、方法名、参数名已经指定&#xff0c;请勿修改&#xff0c;直接返回方法规定的值即可*** param nums int整型…

日本二次元团建国内院线:一周一部,占据36.2%票房

从《你想活出怎样的人生》开始&#xff0c;到《哈尔的移动城堡》结束&#xff0c;日本动画正在占据国内院线的整个4月份档期。 包括《数码宝贝02&#xff1a;最初的召唤》、《间谍过家家 代号&#xff1a;白》多部作品在内&#xff0c;整个国内四月份院线日本动画平均一周上映…

【Linux实践室】Linux高级用户管理实战指南:Linux用户与用户组编辑操作详解

&#x1f308;个人主页&#xff1a;聆风吟_ &#x1f525;系列专栏&#xff1a;Linux实践室、网络奇遇记 &#x1f516;少年有梦不应止于心动&#xff0c;更要付诸行动。 文章目录 一. ⛳️任务描述二. ⛳️相关知识2.1 &#x1f514;Linux查看用户属性命令2.1.1 &#x1f47b;…

数据结构PT1——线性表/链表

1&#xff1a;顺序存储实现(数组实现) Data&#xff1a; a1 a2 .....ai ai1 .... an .... typedef struct LNode *List; //指向LNode的指针&#xff0c;这是typedef的&#xff0c;你可以随时声明&#xff0c;而不加typedef只是创建一个 struct LNode{ //结构体成员ElementT…

【前端】掌握按钮的显示与隐藏

目录 一、前言二、实现显示与隐藏的四种方式1、CSS属性控制2、JavaScript控制3、Vue.js响应式控制 三、需求背景四、代码实现1、定义变量2、绑定事件3、监听选中的学生4、返回return 五、整体效果1、没有勾选学生2、已勾选学生 六、设置按钮显示与隐藏的优势利弊1、优势2、劣势…

MySQL慢查询怎么办?需要关注Explain的哪些关键字?

目录 1-引言&#xff1a;什么是慢查询1-1 慢查询定义1-2 为什么排查慢查询 2-核心&#xff1a;慢查询排查2-1 慢查询定位2-2 慢查询解决2-2-1 Explain 排查慢查询2-2-2 Explain 重点关键字 3-总结&#xff1a;慢查询知识点小结 1-引言&#xff1a;什么是慢查询 1-1 慢查询定义…

C# 字面量null对于引用类型变量✓和值类型变量×

编译器让相同的字符串字面量共享堆中的同一内存位置以节约内存。 在C#中&#xff0c;字面量&#xff08;literal&#xff09;是指直接表示固定值的符号&#xff0c;比如数字、字符串或者布尔值。而关键字&#xff08;keyword&#xff09;则是由编程语言定义的具有特殊含义的标…

羊大师解读,春季羊奶VS夏季羊奶

羊大师解读&#xff0c;春季羊奶VS夏季羊奶 夏季的羊奶和春季的羊奶在营养成分上并没有本质的区别&#xff0c;都含有丰富的蛋白质、矿物质和维生素等。然而&#xff0c;由于季节和气候的变化&#xff0c;人们饮用羊奶的需求和效果可能会有所不同。 在夏季&#xff0c;天气炎热…

C语言 | Leetcode C语言题解之第35题搜索插入位置

题目&#xff1a; 题解&#xff1a; int searchInsert(int* nums, int numsSize, int target) {int left 0, right numsSize - 1, ans numsSize;while (left < right) {int mid ((right - left) >> 1) left;if (target < nums[mid]) {ans mid;right mid - …

使用vue3+ts+vite从零开始搭建bolg(二)

二、全局变量 2.1element-ui集成 pnpm i element-plus pnpm i element-plus element-plus/icons-vue main.ts配置文件 import ElementPlus from element-plus import element-plus/dist/index.css //ts-ignore import zhCn from element-plus/dist/locale/zh-cn.mjsapp.use…

浅说深度优先搜索(中)——回溯

写在最前 相信在你们不懈的努力之下&#xff0c;基本的递归一定可以写出来了&#xff0c;那么我们现在就来看看递归的升级版——回溯怎么写吧&#xff01; 简说回溯 递归是一种特别重要的解题策略。大部分题目需要找到最优解&#xff0c;而这个求解过程可能存在一定的规律性…

UE5(基础动作)多人游戏制作蹲伏

1.创建输入操作&#xff0c;IA_Crouch 在输入映射中添加 IA_Crouch,在触发器中创建两个索引&#xff0c;已按下已松开来创建蹲伏输入。 蹲伏操作必须要勾选角色-角色移动-crouch勾选可蹲伏否则你的人物无法真正蹲下。 为蹲伏创建函数&#xff0c;创建布尔来判断是否蹲伏。 通过…