Swagger系列:Spring Boot 2.x集成Spring Doc(Swagger 3.0)

一、简介

Swagger 是一个 RESTful API 的开源框架,它的主要目的是帮助开发者设计、构建、文档化和测试 Web API。Swagger 的核心思想是通过定义和描述 API 的规范、结构和交互方式,以提高 API 的可读性、可靠性和易用性,同时降低 API 开发的难度和开发者之间的沟通成本。

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定义和管理平台。

其实**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的支持和规范化,提供了更丰富和灵活的定义方式,并且可以用于自动生成文档、客户端代码、服务器代码和测试工具等。

1、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的方式。

2、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这个优秀的工具。

注:Spring Boot 3.0 使用 springdoc-openapi-starter-webmvc-ui坐标

官网地址:springdoc.org/

二、集成

我们在SpringBoot中想集成Swagger3.0,一般不选择原生的Maven坐标,而是选择 springdoc-openapi-ui的Maven坐标,它可以很好的和Spring或SpringBoot项目集成;这个坐标也被Spring社区广泛支持和认可,并被认为是集成Swagger UI和OpenAPI规范的一个优秀选择。下面将直接介绍使用。

1.环境

jdk:1.8

Idea:2023.2

Spring-boot:2.7.15

1. 引入Maven依赖

xml 复制代码
    <dependencies>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>
      
        <dependency>
            <groupId>org.projectlombok</groupId>
            <artifactId>lombok</artifactId>
            <optional>true</optional>
        </dependency>

        <!-- 这个坐标它提供了一组注解和工具来集成Swagger UI和OpenAPI规范等-->
        <!-- https://mvnrepository.com/artifact/org.springdoc/springdoc-openapi-ui -->
        <dependency>
            <groupId>org.springdoc</groupId>
            <artifactId>springdoc-openapi-ui</artifactId>
            <version>1.7.0</version>
        </dependency>
    </dependencies>

2.配置SpringDocConfig(配置类方式)

注:io.swagger.v3.oas.annotations 是Swagger注解包,而io.swagger.v3.oas.models是Swagger配置类对象方式

其实我们通过配置类的方式创建一个OpenAPI的Bean对象就可以创建Swagger3.0的文档说明,下面我就直创建。

scss 复制代码
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属性的值。

SpringDocConfig.java

java 复制代码
package com.mcode.swaggertest.config;

import io.swagger.v3.oas.annotations.enums.SecuritySchemeType;
import io.swagger.v3.oas.models.Components;
import io.swagger.v3.oas.models.ExternalDocumentation;
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 io.swagger.v3.oas.models.security.SecurityScheme;
import io.swagger.v3.oas.models.servers.Server;
import org.springdoc.core.GroupedOpenApi;
import org.springframework.boot.SpringBootConfiguration;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;

/**
 * ClassName: SpringDocConfig
 * Package: com.mcode.swaggertest.config
 * Description:
 *
 * @Author: robin
 * @Create: 2023/9/9 - 7:00 PM
 * @Version: v1.0
 */

@Configuration
public class SpringDocConfig {

//    @Bean
//    public GroupedOpenApi productApi() {
//        return GroupedOpenApi.builder()
//                .group("product-service")
//                .pathsToMatch("/product/**")
//                .build();
//    }
//
//    @Bean
//    public GroupedOpenApi orderApi() {
//        return GroupedOpenApi.builder()
//                .group("order-service")
//                .pathsToMatch("/order/**")
//                .build();
//    }

    @Bean
    public OpenAPI openAPI(){
       // 联系人信息(contact),构建API的联系人信息,用于描述API开发者的联系信息,包括名称、URL、邮箱等
        Contact contact = new Contact()
                .name("robin")  // 作者名称
                .email("code9342@gmail.com") // 作者邮箱
                .url("https://www.cnblogs.com/vic-tory/") // 介绍作者的URL地址
                .extensions(new HashMap<String,Object>());// 使用Map配置信息(如key为"name","email","url")

        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("Api接口文档标题")      // Api接口文档标题(必填)
                .description("项目描述")     // Api接口文档描述
                .version("1.0.0")                                  // Api接口版本
                .termsOfService("https://www.cnblogs.com/vic-tory/")    // Api接口的服务条款地址
                .license(license)  //   授权名称                                
                .contact(contact); // 设置联系人信息

         List<Server>  servers = new ArrayList<>(); //多服务
         // 表示服务器地址或者URL模板列表,多个服务地址随时切换(只不过是有多台IP有当前的服务API)
         servers.add(new Server().url("http://localhost:8080").description("服务1"));
         servers.add(new Server().url("http://localhost:8081").description("服务2"));

        // // 设置 spring security apikey accessToken 认证的请求头 X-Token: xxx.xxx.xxx
        SecurityScheme securityScheme = new SecurityScheme()
                .name("x-token") 
                .type(SecurityScheme.Type.APIKEY)
                .description("APIKEY认证描述")
                .in(SecurityScheme.In.HEADER);

        // 设置 spring security jwt accessToken 认证的请求头 Authorization: Bearer xxx.xxx.xxx
        SecurityScheme securityScheme1 = new SecurityScheme()
                .name("JWT认证")
                .scheme("bearer") //如果是Http类型,Scheme是必填
                .type(SecurityScheme.Type.HTTP)
                .description("认证描述")
                .in(SecurityScheme.In.HEADER)
                .bearerFormat("JWT");

        List<SecurityRequirement> securityRequirements = new ArrayList<>();

        SecurityRequirement securityRequirement = new SecurityRequirement();
        securityRequirement.addList("authScheme");

        securityRequirements.add(securityRequirement);

        // 返回信息
        return new OpenAPI()
                //.openapi("3.0.1")  // Open API 3.0.1(默认)
                .info(info)
                .servers(servers)
                .components(new Components().addSecuritySchemes("authScheme",securityScheme1)) //添加鉴权组件
                .security(securityRequirements) //全部添加鉴权小锁
                .externalDocs(new ExternalDocumentation()
                        .description("对外说明") //对外说明
                        .url("https://www.cnblogs.com/vic-tory/"));       // 配置Swagger3.0描述信息
    }
}

3.配置SpringDocConfig(注解方式)

css 复制代码
定义Swagger3.0配置信息注解:@OpenAPIDefinition (具体参考 io.swagger.v3.oas.annotations)
注意:这个注解全局只能配置一个,主要配置文档信息和安全配置
    说明:用于描述整个API的元信息和全局属性,可以定义和描述,包括API版本、基本信息、服务器信息、安全方案等
    常用属性:
        ①:info:用于描述 API 基本信息的对象,包括标题、版本号、描述等属性;
        ②:servers:用于描述 API 服务的 URL 和配置信息的数组;
        ③:security:用于描述 API 安全方案的数组,其中每个安全方案包含多个安全需求;
        ④:tags:用于描述 API 标签的数组,每个标签包含名称、描述等属性;
        ⑤:externalDocs:用于描述外部文档链接的对象,包含描述和 URL 两个属性。

SpringDocConfig.java

java 复制代码
package com.mcode.swaggertest.config;

import io.swagger.v3.oas.annotations.ExternalDocumentation;
import io.swagger.v3.oas.annotations.OpenAPIDefinition;
import io.swagger.v3.oas.annotations.enums.SecuritySchemeIn;
import io.swagger.v3.oas.annotations.enums.SecuritySchemeType;
import io.swagger.v3.oas.annotations.extensions.Extension;
import io.swagger.v3.oas.annotations.extensions.ExtensionProperty;
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.security.SecurityRequirement;
import io.swagger.v3.oas.annotations.security.SecurityScheme;
import io.swagger.v3.oas.annotations.servers.Server;
import org.springframework.context.annotation.Configuration;

/**
 * ClassName: SpringDocConfig
 * Package: com.mcode.swaggertest.config
 * Description:
 *
 * @Author: robin
 * @Create: 2023/9/9 - 7:00 PM
 * @Version: v1.0
 */

@Configuration
@OpenAPIDefinition(
        info = @Info(
                title = "Api接口文档标题",
                description = "项目描述",
                version = "1.0.0",
                termsOfService = "https://www.cnblogs.com/vic-tory/",
                contact = @Contact(
                        name = "robin",                            // 作者名称
                        email = "code9342@gmail.com",                  // 作者邮箱
                        url = "https://www.cnblogs.com/vic-tory/"  // 介绍作者的URL地址
                ),
                license = @License(name = "Apache 2.0",
                        url = "http://www.apache.org/licenses",
                        extensions = @Extension(name = "test", properties = @ExtensionProperty(name = "test", value = "1111")))
        ),
        security = @SecurityRequirement(name = "JWT认证"), //全部加上认证
        servers = {
                @Server(url = "http://localhost:8081", description = "服务1"),
                @Server(url = "http://localhost:8080", description = "服务2")
        },
        externalDocs = @ExternalDocumentation(description = "对外说明", url = "https://www.cnblogs.com/vic-tory/")
)
@SecurityScheme(
        name = "JWT认证",                   // 认证方案名称
        type = SecuritySchemeType.HTTP,      // 认证类型,当前为http认证
        description = "这是一个认证的描述详细",  // 描述信息
        in = SecuritySchemeIn.HEADER,        // 代表在http请求头部
        scheme = "bearer",                   // 认证方案,如:Authorization: bearer token信息
        bearerFormat = "JWT")
public class SpringDocConfig2 {
}

4.配置API接口信息说明

配置文档标题及归类,就是在Controller上配置。

less 复制代码
注解:@Tag 可以用于对接口进行分类和归类,便于开发人员组织和管理 API 文档
    具体属性:
        ①:name:表示标签的名称,必填属性,也得注意多个Controller上的name不要写一样的,这样就会把它们归类在一起。
        ②:description:表示标签的描述信息,非必填属性。
        ③:externalDocs:用于指定URL地址文档信息来追加描述接口的信息。非必填属性。
        示例:
            @Tag(name = "用户控制器", description = "用户控制器描述",
                externalDocs = @ExternalDocumentation(
                description = "文档接口描述",
                url = "https://www.cnblogs.com/vic-tory/"))

配置文档下的每一个接口信息,就是Controller里的每一个RequestMapping

less 复制代码
注解:@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 = "根据用户标识号查询用户信息",
            description = "根据用户标识号查询用户信息,并返回响应结果信息",
//            security = @SecurityRequirement(name = "authScheme"), //定义单个认证
            parameters = {
                    @Parameter(name = "id", description = "用户标识号", required = true, example = "1")
            },
            responses = {
                    @ApiResponse(
                            responseCode = "200",
                            description = "响应成功",
                            content = @Content(
                                    mediaType = "application/json",
                                    schema = @Schema(
                                            title = "ApiResult和User组合模型",
                                            description = "返回实体,ApiResult内data为User模型",
                                            anyOf = {ApiResult.class, User.class}),
                                    examples = @ExampleObject(
                                            name = "返回示例",
                                            summary = "返回示例",
                                            value =
                                                    "{\n" +
                                                            "  \"code\": 0,\n" +
                                                            "  \"msg\": \"操作成功\",\n" +
                                                            "  \"data\": {},\n" +
                                                            "  \"isSuccess\": true\n" +
                                                            "}"
                                    )
                            )
                    ),

配置请求接口参数信息

less 复制代码
注解:@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", description = "用户标识号", required = true, example = "1")
            },

配置具体的实体模型信息

less 复制代码
注解:@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(
                                            title = "ApiResult和User组合模型",
                                            description = "返回实体,ApiResult内data为User模型",
                                            anyOf = {ApiResult.class, User.class}),
                                    examples = @ExampleObject(
                                            name = "返回示例",
                                            summary = "返回示例",
                                            value =
                                                    "{\n" +
                                                            "  \"code\": 0,\n" +
                                                            "  \"msg\": \"操作成功\",\n" +
                                                            "  \"data\": {},\n" +
                                                            "  \"isSuccess\": true\n" +
                                                            "}"
                                    )
                            )
                    ),

5.配置API接口信息示例

通用返回对象定义

java 复制代码
package com.mcode.swaggertest.common;

import io.swagger.v3.oas.annotations.media.Schema;
import lombok.AllArgsConstructor;
import lombok.Data;

/**
 * ClassName: ApiResult
 * Package: com.mcode.swaggertest.common
 * Description:
 *
 * @Author: robin
 * @Create: 2023/9/9 - 7:29 PM
 * @Version: v1.0
 */

// 响应对象模型定义
@Data
@AllArgsConstructor
@Schema(description = "响应返回数据对象")
public class ApiResult {

    @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;

    @Schema(title = "isSuccess",
            description = "是否成功",
            accessMode = Schema.AccessMode.READ_ONLY,
            format = "boolean",
            requiredMode = Schema.RequiredMode.REQUIRED)
    private Boolean isSuccess;

    public static ApiResult success(Object data) {
        return new ApiResult(1, "操作成功", data, true
        );
    }

    public static ApiResult fail(String msg) {
        return new ApiResult(0, msg, null, false);
    }
}

模型定义

java 复制代码
package com.mcode.swaggertest.entity;

import io.swagger.v3.oas.annotations.media.Schema;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;

/**
 * ClassName: User
 * Package: com.mcode.swaggertest.entity
 * Description:
 *
 * @Author: robin
 * @Create: 2023/9/9 - 7:20 PM
 * @Version: v1.0
 */
@Data
@AllArgsConstructor
@NoArgsConstructor
@Schema(title = "用户实体",description = "用户实体描述")
public class User {
    @Schema(name = "用户标识号", description = "用户标识号描述", format = "int32", example = "1")
    private Integer id;
    @Schema(name = "用户名", description = "用户名描述", example = "robin")
    private String name;
    @Schema(name = "邮件", description = "邮件描述", example = "code9342@gmail.com")
    private String email;
    @Schema(name = "密码", description = "密码描述", example = "123456")
    private String password;
    @Schema(name = "电话号码", description = "电话号码描述", example = "17873041739")
    private String phone;
}

接口定义

java 复制代码
package com.mcode.swaggertest.controller;

import com.mcode.swaggertest.common.ApiResult;
import com.mcode.swaggertest.entity.User;
import io.swagger.v3.oas.annotations.ExternalDocumentation;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.Parameter;
import io.swagger.v3.oas.annotations.media.Content;
import io.swagger.v3.oas.annotations.media.ExampleObject;
import io.swagger.v3.oas.annotations.media.Schema;
import io.swagger.v3.oas.annotations.responses.ApiResponse;
import io.swagger.v3.oas.annotations.security.SecurityRequirement;
import io.swagger.v3.oas.annotations.tags.Tag;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

/**
 * ClassName: UserController
 * Package: com.mcode.swaggertest.controller
 * Description:
 *
 * @Author: robin
 * @Create: 2023/9/9 - 6:59 PM
 * @Version: v1.0
 */
@RestController
@RequestMapping("/user")
@Tag(name = "用户控制器", description = "用户控制器描述",
        externalDocs = @ExternalDocumentation(
                description = "文档接口描述",
                url = "https://www.cnblogs.com/vic-tory/"))
public class UserController {
    /**
     * 根据ID查询用户信息(单条)
     * @param id
     * @return User
     */
    @GetMapping("/get/{id}")
    @Operation(
            summary = "根据用户标识号查询用户信息",
            description = "根据用户标识号查询用户信息,并返回响应结果信息",
//            security = @SecurityRequirement(name = "authScheme"), //定义单个认证
            parameters = {
                    @Parameter(name = "id", description = "用户标识号", required = true, example = "1")
            },
            responses = {
                    @ApiResponse(
                            responseCode = "200",
                            description = "响应成功",
                            content = @Content(
                                    mediaType = "application/json",
                                    schema = @Schema(
                                            title = "ApiResult和User组合模型",
                                            description = "返回实体,ApiResult内data为User模型",
                                            anyOf = {ApiResult.class, User.class}),
                                    examples = @ExampleObject(
                                            name = "返回示例",
                                            summary = "返回示例",
                                            value =
                                                    "{\n" +
                                                            "  \"code\": 0,\n" +
                                                            "  \"msg\": \"操作成功\",\n" +
                                                            "  \"data\": {},\n" +
                                                            "  \"isSuccess\": true\n" +
                                                            "}"
                                    )
                            )
                    ),
                    @ApiResponse(
                            responseCode = "500",
                            description = "响应失败",
                            content = @Content(
                                    mediaType = "application/json",
                                    schema = @Schema(
                                            title = "ApiResult和User组合模型",
                                            description = "返回实体,ApiResult内data为null",
                                            implementation = ApiResult.class)
                            )
                    )
            }
    )
    public User get(@PathVariable(value = "id") Integer id) {
        User user = new User();
        user.setId(1);
        user.setName("robin");
        user.setEmail("code9342@gmail.com");
        user.setPassword("123456");
        user.setPhone("17873041739");
        return user;
    }
}

三、效果图

总览

鉴权

接口定义信息

响应定义信息

模型定义信息

四、配置属性

文档地址:springdoc.org/#properties

配置示例

application.yml

yaml 复制代码
springdoc:
  api-docs:
    enabled: true # 是否开启
    path: '/docs'
  swagger-ui:
    path: ''

有事联系微信:17873041739a-codeboy

相关推荐
m0_748251723 分钟前
Spring Boot——统一功能处理
java·spring boot·后端
love静思冥想4 分钟前
Apache Commons Pool :介绍与使用
java·apache·线程池优化
xmh-sxh-131434 分钟前
常用的前端框架有哪些
java
老马啸西风38 分钟前
NLP 中文拼写检测纠正论文 A Hybrid Approach to Automatic Corpus Generation 代码实现
java
小蒜学长39 分钟前
基于Spring Boot的宠物领养系统的设计与实现(代码+数据库+LW)
java·前端·数据库·spring boot·后端·旅游·宠物
L.S.V.40 分钟前
Java 溯本求源之基础(三十一)——泛型
java·开发语言
Redamancy_Xun1 小时前
开源软件兼容性可信量化分析
java·开发语言·程序人生·网络安全·测试用例·可信计算技术
IDRSolutions_CN1 小时前
(教程)用 Java 从 PDF 中提取嵌入的文件
java·经验分享·pdf·软件工程·团队开发
海波东1 小时前
单例模式懒汉式、饿汉式(线程安全)
java·安全·单例模式
lwprain1 小时前
解决tomcat双击startup.bat乱码的几种方法
java·tomcat