Swagger 官网地址:swagger.io/
SpringDoc官网地址:springdoc.org/
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. OpenAPI 规范
OpenAPI规范(简称OAS)最初由开发Swagger的团队在2010年推出,从Swagger 2.0开始,Swagger规范被正式更名为OpenAPI规范,并得到了许多社区的支持和贡献。
OpenAPI规范(也称为 Swagger 3.x 规范) 是一种用于描述RESTful API的标准化格式,它定义了如何描述API的基本信息、结构、参数、响应等方面的规范。
OpenAPI规范以机器可读的方式定义了RESTful API的结构和特征,支持自动生成文档、客户端与服务端代码、Mock Server和测试工具等。
OpenAPI规范采用JSON或YAML格式编写,并支持多种数据类型,可以描述API的基本信息、路径、HTTP方法、参数、响应等各种细节。
通过遵循OpenAPI规范,开发者可以快速定义和构建RESTful API,并且可以生成相应的文档和代码来帮助他们更快地开发与测试API。同时,OpenAPI规范还可以促进不同系统之间的交互和集成,因为根据规范定义的API可以被多个客户端程序和服务端程序所理解和使用。
3. Spring 生态的API文档工具
3.1 SpringFox工具
Springfox是一套可以帮助Java开发者自动生成API文档的工具,它是基于Swagger 2.x基础上开发的。 Springfox是一个用于集成Swagger2.x到Spring应用程序中的库。Springfox 提供了一些注解来描述API接口、参数和返回值,并根据这些信息生成Swagger UI界面 ,从而方便其他开发人员查看和使用您的API接口。
Springfox还支持自动生成API文档和代码片段,简化了开发人员的工作量。除了集成Swagger 2.x,Springfox还提供了一些额外功能,例如自定义Swagger文档、API版本控制、请求验证等等
但随着Swagger2.x终究成为历史,springfox-boot-starter的坐标从3.0.0版本(2020年7月14日)开始就一直没有更新;所以不再推荐使用。
3.2 SpringDoc工具
SpringDoc对应坐标是springdoc-openapi-ui,它是一个集成Swagger UI和ReDoc的接口文档生成工具,在使用上与springfox-boot-starter类似,但提供了更为灵活、功能更加强大的工具。
SpringDoc支持全新的OpenAPI 3.0规范,可以生成Swagger UI风格的接口文档,还提供了ReDoc的文档渲染方式,可以自动注入OpenAPI规范的JSON描述文件,支持OAuth2、JWT等认证机制。
SpringDoc是基于OpenAPI 3.0规范构建的,因此推荐在Spring Boot 2.4及以上版本中使用。
因为SpringDoc有更先进的技术架构和更好的扩展性,使其基本取代了springfox-boot-starter工具包,成为了当前Spring Boot生态中最受欢迎的API文档工具之一。
4. SpringBoot 中集成 SpringDoc
4.1 Springdoc OpenAPI的依赖项
引入springdoc openapi依赖时,需要先确认一下SpringBoot所使用的Web框架:
- Spring MVC ,基于 Servlet 的框架,是 Spring Framework 的一部分,用于构建 web 应用程序。
- Spring WebFlux ,是 Spring 5 引入的一个新模块,用于构建响应式 web 应用程序。
根据项目所使用的Web框架,选择相应的starter依赖项:
- Spring MVC:使用
springdoc-openapi-starter-webmvc-ui
- Spring WebFlux:使用
springdoc-openapi-starter-webflux-ui
- 如需要同时支持 Spring MVC 和 Spring WebFlux:则使用
springdoc-openapi-starter-ui
以下是被starter所包含的依赖项,不需要直接引入:
springdoc-openapi-common
:提供了 Springdoc OpenAPI 的一些通用功能。springdoc-openapi-core
:是 Springdoc OpenAPI 的核心,提供生成 OpenAPI 文档的核心功能。- springdoc-openapi-ui:提供了一个 web 界面,用于查看和测试 OpenAPI 文档。
如果 API 使用了安全机制(如 OAuth2 或 JWT),则需要引入单独的 springdoc-openapi-security依赖项,它提供了与安全相关的功能,例如处理 OpenAPI 的 securityScheme 和 securityRequirement。
项目中最常用的,是springdoc-openapi-starter-webmvc-ui
:
⚠️注意:
当引入Mockserver时,其内置的swagger模块会和swagger3产生版本冲突,导致报以下错误:
Failed to instantiate [org.springdoc.core.converters.ModelConverterRegistrar]:
Factory method 'modelConverterRegistrar' threw exception with message:
'io.swagger.v3.core.converter.ModelConverters
io.swagger.v3.core.converter.ModelConverters.getInstance(boolean)'
解决方法是将MockServer中的swagger模块排除掉:
<dependency>
<groupId>org.mock-server</groupId>
<artifactId>mockserver-netty</artifactId>
<version>${mockserver.version}</version>
<exclusions>
<exclusion>
<groupId>io.swagger.parser.v3</groupId>
<artifactId>swagger-parser</artifactId>
</exclusion>
<exclusion>
<groupId>io.swagger.parser.v3</groupId>
<artifactId>swagger-models</artifactId>
</exclusion>
</exclusions>
</dependency>
4.2 配置OpenAPI
OpenAPI有两种配置方式:
- 注解的配置方式,对应的包是:io.swagger.v3.oas.annotations
- 类对象的配置方式,对应的包是:io.swagger.v3.oas.models
4.2.1 注解配置方式
@SpringBootConfiguration
@OpenAPIDefinition(
// API的基本信息,包括标题、版本号、描述、联系人等
info = @Info(
title = "Swagger3.0 (Open API) 示例文档", // Api接口文档标题(必填)
description = "Swagger框架测试接口", // Api接口文档描述
version = "1.0.0", // Api接口版本
termsOfService = "https://example.com/", // Api接口的服务条款地址
contact = @Contact(
name = "FirstName LastName", // 作者姓名
email = "contact@example.com", // 作者邮箱
url = "https://url/" // 作者的URL地址
),
license = @License( // 设置Lisence信息
name = "Apache 2.0",
url = "https://www.apache.org/licenses/LICENSE-2.0.html"
)
),
security = @SecurityRequirement(name = "JWT-test"),
// 服务器地址列表,用于在页面上执行测试时切换
servers = {
@Server(url = "http://devIp:port", description = "测试环境服务器"),
@Server(url = "http://prodIp:port", description = "生产环境服务器"),
},
externalDocs = @ExternalDocumentation(description = "更多内容", url = "xxx"))
@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")
public class SwaggerOpenApiConfig {}
4.2.2 类对象配置方式
类对象的配置方式是创建一个OpenAPI的Bean对象。
OpenAPI对象用于描述整个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的标签信息,用于对相似的操作进行分组。
示例代码如下:
@Configuration
public class OpenAPIConfig {
@Bean
public OpenAPI myOpenAPI() {
// 定义测试环境服务器URL
String devUrl = "http://localhost:8999";
Server devServer = new Server();
devServer.setUrl(devUrl);
devServer.setDescription("测试环境的服务器URL");
// 定义生产环境服务器URL
String prodUrl = "http://localhost:8999";
Server prodServer = new Server();
prodServer.setUrl(prodUrl);
prodServer.setDescription("正式环境的服务器URL");
// 定义联系人对象
Contact contact = new Contact();
contact.setEmail("contact@example.com");
contact.setName("FirtName LastName");
contact.setUrl("https://www.example.com");
License mitLicense = new License().name("MIT License")
.url("https://choosealicense.com/licenses/mit/");
// 定义API信息对象
Info info = new Info()
.title("Spring Doc 演示 API")
.version("1.0")
.contact(contact)
.description("对外API接口说明.")
.termsOfService("https://www.sanfate.com/terms")
.license(mitLicense);
// 返回OpenAPI对象,包含API信息和服务器信息
return new OpenAPI().info(info)
.servers(List.of(devServer, prodServer));
}
}
5. SpringDoc扫描的内容
SpringDoc扫描项目源码中的以下内容:
- Controller 和接口方法:扫描所有标记为 @RestController 或 @Controller 的类。
- DTO/POJO 类(模型):扫描作为请求和响应对象的自定义类(DTO/POJO),并生成相应的 Schema。 SpringDoc的页面中,只显示这两种内容:接口,Schema,如下图所示:
注意⚠️:
如果源码中接口的注解方式,使用的注解为 @ReqeustMapping ,而不是具体的 @GetMapping,@PostMapping等,由于SpirngDoc无法获知具体的接口类型,就会为其生成全部七个类型的RESTFUL接口文档:GET, POST, PUT, PATCH, DELETE, HEAD, OPTION,再加上多个接口,会使得页面非常杂乱。因此建议要明确指定接口的类型,不要使用通用的@ReqeustMapping。
6. SpringDoc的注解
SpringDoc注解的核心目的,是为了获得更详细的接口或Schema的描述信息。
各种注解的详细信息,参考官网说明:spec.openapis.org/oas/latest.…
6.1 @Tag 注解
@Tag 可以用于对接口进行分类和归类,便于开发人员组织和管理 API 文档。其属性包括:
- ①:name:表示标签的名称,必填属性,如果多个Controller上的name写一样的,就会把它们归类在一起。
- ②:description:表示标签的描述信息,非必填属性。
- ③:externalDocs:用于指定URL地址文档信息来追加描述接口的信息。非必填属性。
@Tag(
name = "StudentControllerAPI",
description = "学生控制器接口",
externalDocs = @ExternalDocumentation(
description = "这是一个接口文档介绍",
url = "https://www.cnblogs.com/antLaddie/")
)
6.2 @Operation注解
@Operation 注解用于对API操作(即方法)进行描述和标记。具体属性如下:
- ①: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})
)
)
}
)
6.3 @Parameter注解
@Parameter用于描述HTTP请求的参数信息,它是一个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:参数值的示例;
6.4 @Schema注解
@Schema 是用于描述数据模型的基本信息和属性
6.4.1 常规属性
- ①: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:用于显示为该类或属性引入具体的实体路径,这代表当前指定的类或者属性将参考引入的实体。
6.4.2 type属性
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属性引入。
6.4.3 复杂类型的描述属性
@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来描述这种情况。
7. API接口注解示例
全局基本信息配置好了之后,就可以开始对API接口添加注解。
7.1 响应对象定义
@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;
}
7.2 实体定义
// 模型定义示例:
@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; // 学生爱好
}
7.3 接口定义
@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);
}
}
8. 权限认证方式:@SecurityScheme注解
接口一半都是有权限校验方式的,每个接口在请求时都是包含校验,如常见的JWT校验,访问每个接口都需要携带Token信息,下面简单介绍校验认证的方式描述。
权限设置的注解是:@SecurityScheme ,用于定义API的安全方案。
通过使用@SecurityScheme注解,可以为API定义多种安全方案,并指定每种方案的相关属性, 例如认证类型、授权URL、令牌URL、作用域等。
@SecurityScheme
常用属性:
- 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等。
比如添加了一个名称为”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")
)
9. Swagger-UI查看接口文档
按照上述要求完成OpenApi的使用后,可以基于Swagger-UI的界面,查看本项目的接口文档: 浏览器输入地址:http://ip:port/swagger-ui.html
其中,ip和port是本项目运行的地址和端口;
页面样式:
10. Knife4j 的使用
Knife4j 是基于 Swagger UI 的增强版本,专为中国开发者社区设计,主要目的是改善Swagger-UI比较丑陋的前端页面。它在 springdoc-openapi 和 Swagger 3 的基础上进行了功能扩展,提供了更强大、更易用的 API 文档管理和展示工具。
可惜的是Knife4j目前的最后更新时间截止到2021年,其增强功能只适用于SpringFox(OpenAPI2.x规范)。
使用springdoc-openapi框架而非springfox时,需要使用Knife4j的3.x版本,该版本没有Knife4j提供的部分增强功能,是一个纯Ui,引入如下依赖即可:
<dependency>
<groupId>com.github.xiaoymin</groupId>
<artifactId>knife4j-springdoc-ui</artifactId>
<version>3.0.3</version>
</dependency>
在application.yml中添加配置:
knife4j:
enable: true
setting:
language: zh-CN
Knife4j的页面访问地址:http://ip:port/doc.html
页面样式: