【OpenAPI】Spring3 集成 OpenAPI 生成接口文档

Spring3 集成 OpenAPI 生成接口文档

1. 依赖

Spring 版本:3.0.5

Java 版本:jdk21

OpenAPI 依赖:

<!-- https://mvnrepository.com/artifact/org.springdoc/springdoc-openapi-starter-webmvc-ui -->
<dependency>
    <groupId>org.springdoc</groupId>
    <artifactId>springdoc-openapi-starter-webmvc-ui</artifactId>
    <version>2.6.0</version>
</dependency>

官网:OpenAPI 规范 | OpenAPI 官方文档中文版 (xiniushu.com)

不要包含其他的接口文档的框架,大概率是冲突的

目前我还没有找到 Spring3 的其他接口文档方案,swagger2 和 swagger3 都因为不兼容搞不了;

2. 配置文件

默认整个类路径全扫描

@Configuration
public class OpenApiConfig {

    @Bean
    public OpenAPI springOpenAPI() {
        return new OpenAPI().info(new Info()
                .title("SpringDoc API Test")
                .description("SpringDoc Simple Application Test")
                .version("1.0"));
    }

}

3. 关键用法

3.1 Tag 注解

对接口文档进行分组,一个 controller 类为单位

@RestController
@RequiredArgsConstructor
@RequestMapping("/api/v1")
@Tag(name = "xxx")
public class xxxController {
    
}

3.2 Operation 注解

对接口进行描述,一个目标方法为单位

@PostMapping("/create")
@Operation(summary = "创建一个 XXX")
public SystemJsonResponse<CustomClass> createXXX() {
    
}

3.3 Parameter 与 Header 注解

Parameter 描述一个接口的参数与路径参数,Header 描述一个接口的请求头,他们作用于目标方法的形参

@PostMapping("/get/{id}")
@Operation(summary = "获得一个 XXX")
public SystemJsonResponse<CustomClass> getXXX(@RequestHeader("token") @Header(description = "token") String token,
                                              @PathVariable("id") @Parameter(description = "id") Long id,
                                              @RequestParam(name = "state") @Parameter(description = "state") Integer state) {
}

3.4 Schema 注解

Schema 描述一个数据模型,也可以描述一个属性,作用于类或者字段

name 可指定属性的名称,description 是属性的描述

name 作为数据模型(类)的名称,description 是数据模型(类)的描述

属性得 public 或者有 public 的 Getter 和 Setter,否则会被标注只读或只写,如果都没有则直接忽略,如果一个数据模型属性都没有,忽略这个数据模型,复杂点的情况还会出现莫名其妙的现象

总而言之规范地写就没问题,框架也没义务和精力去控制各种奇奇怪怪地情况,我们也没必要总结

@TableName(value ="user")
@Schema(description = "用户")
@Data
public class User implements Serializable {

    @Schema(description = "ID")
    private Long id;

    @Schema(description = "昵称")
    private String nickname;

    private static final long serialVersionUID = 1L;
}

3.5 SchemaProperty 注解

SchemaProperty 作用于一个字段,无法设置属性名,name 作为属性的描述

这个注解不能作用于自定义的数据模型,自定义对象会被认定为 string,因为这个注解就是作用于普通的字段,并不支持递归扫描,这个时候应该用 Schema

  • 建议都用 Schema,SchemaProperty 功能还是太弱了
@SchemaProperty(name = "ID")
private Long id;

3.6 Hidden

作用于字段,表示忽略字段

@Hidden
private String nickname;

3.7 nullable = true

注解参数设置这个代表参数可以为 null

@Schema(description = "昵称", nullable = true)
private String nickname;

3.8 响应的数据模型

OpenAPI 提供了 @ApiRespnse 注解,但是很不方便,不如直接去 Postman 或者 Apifox 上进行操作,理想状态就是直接扫描出「请求body对象」和「响应body对象」 Schema 注解描述的数据模型

请求的话,作为参数是类型是确定的,OpenAPI 框架自然是扫描的到的,但是响应的数据模型,一般是统一响应格式的:

@Schema(name = "统一响应")
@NoArgsConstructor
@Getter
public class SystemJsonResponse implements Serializable {

    private static final long serialVersionUID = 1L;

    @JsonInclude
    @Schema(description = "状态码")
    private int code;

    @JsonInclude
    @Schema(description = "描述语")
    private String message;

    @JsonInclude
    @Schema(nullable = true)
    private Object data;
}

返回的时候,构造 json 是没问题的,但是框架扫描不出来这个 data 数据模型,因为框架只知道 data 是 Object 类型

你可能想问:“框架拿到 data 用 getClass 不就知道了吗?”

是的,但是接口文档生成是在这个接口被调用之前,所以并没有一个 data 数据提供给框架

你很容易想到用范型来定义统一响应:

@Schema(name = "统一响应")
@NoArgsConstructor
@Getter
public class SystemJsonResponse<T> implements Serializable {

    private static final long serialVersionUID = 1L;

    @JsonInclude
    @Schema(description = "状态码")
    private int code;

    @JsonInclude
    @Schema(description = "描述语")
    private String message;

    @JsonInclude
    @Schema(nullable = true)
    private T data;
}

但是实践这个方式,你会发现生成的接口文档,data 仍然是 object

其实原因很简单,用 @Schema 将 SystemJsonResponse 描述作一个固定的数据模型,那每个以此对象为返回值的目标方法,接口文档都直接使用这个数据模型

而泛型在定义的时候,本质还是 Object

解决方案也很简单,去掉 @Schema 即可,这样框架扫描目标方法返回的 SystemJsonResponse<CustomClass> 的时候,都会创建一个新的数据模型,这个时候就可以通过泛型类型确定准确的响应数据模型了,若存在一个一模一样的才会复用

注意:

  1. 不支持通配符:SystemJsonResponse<?>
  2. SystemJsonResponse<? extends CustomClass>,则仅仅扫描 CustomClass

3.9 补充

GetMapping 的接口,RequestBody 会被扫描成 queryString,而不是 json

4. 访问

http://[host]:[post]/swagger-ui/index.html

http://[host]:[post]/v3/api-docs

在这里插入图片描述

更多细节需要去查去探索这里不一一罗列

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

s:103

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值