在 SpringBoot 中集成 OpenAPI 文档
概述
OpenAPI 是一个规范(Specification),它定义了一种描述 API 的标准化格式,使得这些 API 更容易被人类阅读和机器解析,便于生成文档、测试、客户端代码等。这个规范以前被称为 Swagger 规范,但后来被捐赠给了 Linux 基金会。Swagger 还一系列遵循这些规则的工具和 UI。
在 SpringBoot 中用于生成 OpenAPI 文档的工具有: springfox、springdoc 和 knife4j 等
准备
<!-- SpringFox 已经停更了 -->
<dependency>
<groupId>io.springfox</groupId>
<artifactId>springfox-boot-starter</artifactId>
<version>3.0.0</version>
</dependency>
<!-- SpringDoc 更好的提供了对 OpenAPI3 的支持 -->
<dependency>
<groupId>org.springdoc</groupId>
<artifactId>springdoc-openapi-ui</artifactId>
<version>1.5.13</version>
</dependency>
@EnableOpenApi
常用注解
注解 | 类 | 方法 | 属性 |
---|---|---|---|
@Api(tags) | 标注一个类为 Swagger 资源, 设置资源名称, 默认是类名 | ||
@ApiOperation(value) | 标注一个请求, 设置该请求的名称, 默认是方法名 | ||
@ApiParam | (不常用) 仅用于 JAX-RS | ||
@ApiImplicitParam | (常用) 功能同 @ApiParame, 可用于 Servlet | ||
@ApiImplicitParams | 包裹多个参数描述注解 | ||
@ApiModel | 标注一个实体类 | ||
@ApiModelProperty | 标注实体属性, 设置属性的备注信息 | ||
@ApiResponse | 描述响应码,以及备注信息 | ||
@ApiResponses | 包裹多个响应描述注解 | ||
@ApiIgnore | 使swagger忽略某个资源 | 使swagger忽略某个接口 | 使swagger忽略某个属性 |
摘自 springdoc 官网的注解对比:
SpringFox
配置文档信息
// SpringFox 需要注入一个 Docket 对象配置文档信息, springfox.documentation.spring.web.plugins.Docket 中默认配置了部分属性
// springfox.documentation.spi.service.contexts.Defaults 中配置了一些基本内容
@Configuration
public class SwaggerConfig {
@Bean
public Docket docket() {
return new Docket(DocumentationType.OAS_30)
.groupName("LearnSwagger")
.apiInfo(apiInfo())
.enable(true);
}
private ApiInfo apiInfo() {
return new ApiInfoBuilder()
.title("测试文档标题")
.contact(new Contact("xtyuns", "https://github.com/xtyuns", null))
.description("测试文档描述信息")
.version("v1.0.0")
.build();
}
}
详见 Docket 和 ApiInfo 的源码
文档资源过滤
@Bean
public Docket docket() {
return new Docket(DocumentationType.OAS_30)
.groupName("LearnSwagger")
.select()
.paths(s -> s.startsWith("/v1"))
.build();
}
通过 paths 选取时可以使用 PathSelectors, 其中提供了 any()、none()、ant(antPattern)、regex(pathRegex) 方法。
@Bean
public Docket docket() {
return new Docket(DocumentationType.OAS_30)
.groupName("LearnSwagger")
.select()
.apis(RequestHandlerSelectors.basePackage("com.xtyuns"))
.apis(requestHandler -> "index-controller".equals(requestHandler.groupName()))
.build();
}
// 等同于 (使用 and 连结多个选取方法)
@Bean
public Docket docket() {
return new Docket(DocumentationType.OAS_30)
.groupName("LearnSwagger")
.select()
.apis(
RequestHandlerSelectors.basePackage("com.xtyuns")
.and(
requestHandler -> "index-controller".equals(requestHandler.groupName())
)
).build();
}
// 默认的 Selector
public static final ApiSelector DEFAULT
= new ApiSelector(
(withClassAnnotation(ApiIgnore.class).negate()).and(
(withMethodAnnotation(ApiIgnore.class).negate())), PathSelectors.any());
RequestHandlerSelectors 中也提供了 any()、none()、withClassAnnotation(cls)、withMethodAnnotation(cls) 方法。
requestHandler.groupName() 是类名称的中划线表示法,RequestHandler 类中还有一些其他信息可用于进行断言。
文档分组
可以配置多个 Docket Bean, 必须使用 GroupName 进行区分。
配置示例
SpringDoc
springdoc 大多数配置都与 springfox 类似,如 Docket 变为了 OpenApi 或 GroupedOpenApi
授权
io.swagger.v3.oas.annotations.security.SecurityScheme
@RestController
@Tag(name = "springdoc & security")
@SecuritySchemes({
@SecurityScheme(
name = "byBearer",
type = SecuritySchemeType.HTTP,
scheme = "bearer"
),
@SecurityScheme(
name = "byApiKey",
type = SecuritySchemeType.APIKEY,
in = SecuritySchemeIn.HEADER,
paramName = "customerKey"
),
@SecurityScheme(
name = "byOAuth2Password",
type = SecuritySchemeType.OAUTH2,
flows = @OAuthFlows(
authorizationCode = @OAuthFlow(
authorizationUrl = "http://example.com/oauth2/authorize",
tokenUrl = "http://example.com/oauth2/token"
),
password = @OAuthFlow(
tokenUrl = "http://example.com/oauth2/token"
)
)
)
})
public class IndexController {
@Operation(
summary = "这是默认请求地址",
security = {
@SecurityRequirement(name = "byBearer")
},
responses = {
@ApiResponse(responseCode = "200", description = "请求成功, 响应: ok"),
@ApiResponse(responseCode = "500", description = "服务器内部出错了")
}
)
@GetMapping("")
public ResponseEntity<String> index() {
return ResponseEntity.ok("ok");
}
}
- scheme type: Basic、Bearer
通过 OpenApi 定义 SecurityScheme: https://github.com/OAI/OpenAPI-Specification/blob/main/versions/3.1.0.md#securitySchemeObject
相关阅读
swaggere2 和 swagger3: https://blog.csdn.net/qq_35425070/article/details/105347336
springfox 到 springdoc 迁移指南: https://github.com/springfox/springfox/pull/3935
注解总览: https://github.com/swagger-api/swagger-core/wiki/Swagger-2.X---Annotations#quick-annotation-overview
spring gateway 统一配置 swagger: https://piotrminkowski.com/2020/02/20/microservices-api-documentation-with-springdoc-openapi/
自定义异常处理响应: https://blog.lanweihong.com/posts/1527/