Swagger3 使用教程 - 基础篇

大纲

前言

Swagger 是一系列 RESTful API 的工具,通过 Swagger 可以获得项目的⼀种交互式 API 文档。Swagger 的目标是为 RESTful API 定义一个标准的、与语⾔言无关的接口,使人和计算机在看不到源码、或者看不到文档、或者不能通过网络流量检测的情况下,能发现和理解各种服务的功能。当服务通过 Swagger 定义,用户就能通过少量的实现逻辑与远程的服务互动。

版本说明

Swagger 的版本发展历史

Swagger 从 3.0 版本开始更名为 OpenAPI,通常所说的 Swagger 一般指的是 Swagger 2.x 版本,而 OpenAPI 则指的是 Swagger 3.x 版本。简而言之,Swagger2 是 OpenAPI 规范的前身,Swagger3 是 OpenAPI 规范的官方正式版本。更具体地说,Swagger3 引入了对 OpenAPI 的支持,提供了更简洁的依赖引入方式,接口地址有所改变,注解系统进行了更新,并对 Docket 配置进行了优化。Swagger3 实现了零配置和自动配置支持,同时兼容旧版注解,但文档页面地址和接口地址在不同版本间不兼容。

Swagger2 和 Swagger3 的区别

区别一:引入的依赖不同

  • 引入 Swagger2 的依赖
1
2
3
4
5
6
7
8
9
10
11
<dependency>
<groupId>io.springfox</groupId>
<artifactId>springfox-swagger2</artifactId>
<version>2.9.2</version>
</dependency>

<dependency>
<groupId>io.springfox</groupId>
<artifactId>springfox-swagger-ui</artifactId>
<version>2.9.2</version>
</dependency>
  • 引入 Swagger3 的依赖
1
2
3
4
5
<dependency>
<groupId>io.springfox</groupId>
<artifactId>springfox-boot-starter</artifactId>
<version>3.0.0</version>
</dependency>

区别二:使用的注解不同

  • 启用注解:

    • Swagger2: 使用 @EnableSwagger2 注解来启用 Swagger 的文档化。
    • Swagger3: 使用 @EnableOpenApi 注解来启用 Swagger 的文档化,默认可以不使用,且在新版本中已被移除。
  • 控制器注解

    • Swagger2: 使用 @Api 注解来标注控制器类,表明该类的路径应该被 Swagger 文档化。
    • Swagger3: 使用 @Tag 注解来替代 @Api 注解。Swagger3 会使用更自然的方式来扫描类路径,自动包含所有的控制器类。
  • API 描述注解

    • Swagger2: 使用 @ApiInfo@ApiOperation 注解来描述一个 HTTP 操作。
    • Swagger3: 使用 @Operation 注解来描述一个 HTTP 操作。
  • 参数注解

    • Swagger2: 使用 @ApiParam@ApiImplicitParam@ApiImplicitParams 注解来描述参数。
    • Swagger3: 使用 @Parameter@Parameters 注解来描述参数,它提供了更丰富的属性,如 schema、example 和 content 等。
  • 请求体和响应体注解

    • Swagger2: 使用 @ApiModel@ApiModelProperty 注解来描述请求和响应的数据模型。
    • Swagger3: 引入了 @Schema 注解来描述数据模型,提供了更多的细节和配置选项。
  • 请求响应状态注解

    • Swagger2: 使用 @ApiResponse@ApiResponses 注解来描述响应和错误码。
    • Swagger3: @ApiResponse@ApiResponses 注解仍然可以使用,但是现在可以包含更多的信息,如媒体类型。
  • 安全和授权注解

    • Swagger2: 使用 @Authorization 注解来实现认证授权。
    • Swagger3: 使用 @SecurityRequirement 注解来实现认证授权。

区别三:暴露的 JSON 接口不同

  • Swagger2 暴露的 JSON 接口:http://localhost:8080/v2/api-docs
  • Swagger3 暴露的 JSON 接口:http://localhost:8080/v3/api-docs

区别四:访问的 UI 页面路径不同

  • Swagger2 的 UI 页面路径:http://localhost:8080/swagger-ui.html
  • Swagger3 的 UI 页面路径:http://localhost:8080/swagger-ui/index.html

Swagger3 常用注解

注解列表

注解标注位置作用
@TagController 类描述 Controller 的作用
@Operation 方法描述方法的作用
@Parameter 方法参数描述方法参数
@Parameters 方法参数描述多个方法参数
@ApiResponse 方法描述 HTTP 响应信息
@ApiResponses 方法描述多个 HTTP 响应信息
@SchemaModel 层的 JavaBean 描述模型(Entity、DTO、VO)及每个属性的作用

注解使用

@Tag 注解

@Tag 注解用于描述 Controller 的作用。

1
2
3
4
5
6
7
8
9
10
import io.swagger.v3.oas.annotations.tags.Tag;

@RestController
@RequestMapping("/pay")
@Tag(name = "支付微服务模块", description = "支付CRUD")
public class PayController {

......

}

@Schema 注解

@Schema 注解用于描述模型(Entity、DTO、VO)及每个属性的作用

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
import io.swagger.v3.oas.annotations.media.Schema;

@Table(name = "t_pay")
@Schema(title = "支付交易 Entity")
public class Pay {

@Id
@GeneratedValue(generator = "JDBC")
@Schema(title = "主键")
private Integer id;

/**
* 支付流水号
*/
@Column(name = "pay_no")
@Schema(title = "支付流水号")
private String payNo;

/**
* 订单流水号
*/
@Column(name = "order_no")
@Schema(title = "订单流水号")
private String orderNo;

......

}

@Operation 注解

@Operation 注解用于描述方法的作用。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
import io.swagger.v3.oas.annotations.tags.Tag;
import io.swagger.v3.oas.annotations.Operation;

@RestController
@RequestMapping("/pay")
@Tag(name = "支付微服务模块", description = "支付CRUD")
public class PayController {

@PostMapping("/add")
@Operation(summary = "新增", description = "新增支付流水方法,JSON串作参数")
public String addPay(@RequestBody Pay pay) {
return null;
}

......

}

@Parameter 注解

@Parameter 注解用于描述方法参数。值得一提的是,@Parameter 注解的 in 属性的值有 4 种:queryheaderpathcookie。它们都是用来描述请求参数不在请求体内的情况下,会在哪里。比如:

  • query

    • 配合 GET 请求 + @RequestParam 注解使用
    • 表示参数是以 Query-String 的形式携带在 HTTP 请求地址中,即拼接在 URL 的后面,比如 https://www.example.com?name=Tom
  • header

    • 配合 @RequestHeader 注解使用。
    • 表示参数是 “藏在” HTTP 请求头中传递到后台的。
  • path

    • 配合 @PathVariable 注解使用
    • 表示参数是 “嵌在” HTTP 请求路径中的,即属于 URL 的一部分,比如,https://www.example.com/delete/15947874
  • cookie

    • 表示参数是以 Cookie 的方式传递到后台的,使用较少。

GET 请求,传递 Query-String 参数

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
import io.swagger.v3.oas.annotations.tags.Tag;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.Parameter;
import io.swagger.v3.oas.annotations.enums.ParameterIn;

@RestController
@RequestMapping("/pay")
@Tag(name = "支付微服务模块", description = "支付CRUD")
public class PayController {

@GetMapping("/pay/get/{id}")
@Operation(summary = "按照 ID 查流水", description = "查询支付流水方法")
public Pay getById(@Parameter(in = ParameterIn.PATH, description = "ID", required = true) @PathVariable("id") Integer id) {
return null;
}

......

}

POST 请求,传递 Query-String 参数

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
import io.swagger.v3.oas.annotations.tags.Tag;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.Parameter;
import io.swagger.v3.oas.annotations.enums.ParameterIn;

@RestController
@RequestMapping("/pay")
@Tag(name = "支付微服务模块", description = "支付CRUD")
public class PayController {

@PostMapping("/add")
@Operation(summary = "新增", description = "新增支付流水方法,JSON串作参数")
public String addPay(@Parameter(in = ParameterIn.DEFAULT, description = "", schema = @Schema(implementation = Pay.class)) @RequestBody Pay pay) {
return null;
}

......

}

@ApiResponse 注解

@ApiResponse 注解标注在 Controller 的方法上,用来指定 HTTP 响应信息。

@ApiResponse 单独使用

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.Parameter;
import io.swagger.v3.oas.annotations.enums.ParameterIn;
import io.swagger.v3.oas.annotations.media.Content;
import io.swagger.v3.oas.annotations.media.Schema;
import io.swagger.v3.oas.annotations.responses.ApiResponse;
import io.swagger.v3.oas.annotations.tags.Tag;

@RestController
@RequestMapping("/pay")
@Tag(name = "支付微服务模块", description = "支付CRUD")
public class PayController {

@GetMapping("/pay/get/{id}")
@Operation(summary = "按照 ID 查流水", description = "查询支付流水方法")
@ApiResponse(responseCode = "200", description = "OK", content = @Content(mediaType = "application/json", schema = @Schema(implementation = String.class)))
public Pay getById(@Parameter(in = ParameterIn.PATH, description = "ID", required = true) @PathVariable("id") Integer id) {
return null;
}

......

}

@ApiResponse 和 @ApiResponses 注解组合使用

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.Parameter;
import io.swagger.v3.oas.annotations.enums.ParameterIn;
import io.swagger.v3.oas.annotations.media.Content;
import io.swagger.v3.oas.annotations.media.Schema;
import io.swagger.v3.oas.annotations.responses.ApiResponse;
import io.swagger.v3.oas.annotations.responses.ApiResponses;
import io.swagger.v3.oas.annotations.tags.Tag;

@RestController
@RequestMapping("/pay")
@Tag(name = "支付微服务模块", description = "支付CRUD")
public class PayController {

@GetMapping("/pay/get/{id}")
@Operation(summary = "按照 ID 查流水", description = "查询支付流水方法")
@ApiResponses(value = {
@ApiResponse(responseCode = "200", description = "OK", content = @Content(mediaType = "application/json", schema = @Schema(implementation = String.class))),
@ApiResponse(responseCode = "400", description = "Bad Request", content = @Content(mediaType = "application/json", schema = @Schema(implementation = Object.class))),
@ApiResponse(responseCode = "500", description = "Internal Server Error", content = @Content(mediaType = "application/json", schema = @Schema(implementation = Object.class)))})
public Pay getById(@Parameter(in = ParameterIn.PATH, description = "ID", required = true) @PathVariable("id") Integer id) {
return null;
}

......

}

SpringBoot3 整合 Swagger3

引入依赖

  • 引入 Swagger3 的 SpringBoot Starter
1
2
3
4
<dependency>
<groupId>org.springdoc</groupId>
<artifactId>springdoc-openapi-starter-webmvc-ui</artifactId>
</dependency>

添加配置类

  • 添加 Swagger3 的配置类
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
import io.swagger.v3.oas.models.ExternalDocumentation;
import io.swagger.v3.oas.models.OpenAPI;
import io.swagger.v3.oas.models.info.Info;
import org.springdoc.core.models.GroupedOpenApi;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

@Configuration
public class Swagger3Config {

@Bean
public GroupedOpenApi PayApi() {
return GroupedOpenApi.builder().group("支付微服务模块").pathsToMatch("/pay/**").build();
}

@Bean
public GroupedOpenApi OtherApi() {
return GroupedOpenApi.builder().group("其它微服务模块").pathsToMatch("/other/**", "/others").build();
}

@Bean
public GroupedOpenApi CustomerApi() {
return GroupedOpenApi.builder().group("客户微服务模块").pathsToMatch("/customer/**", "/customers").build();
}

@Bean
public OpenAPI docsOpenApi() {
return new OpenAPI().info(new Info().title("Spring Cloud").description("API 文档").version("v1.0"))
.externalDocs(new ExternalDocumentation().description("www.example.com").url("https://www.example.com/"));
}

}

访问 UI 页面

  • 启动 SpringBoot 应用后,浏览器访问 Swagger3 的 UI 页面,比如 http://127.0.0.1:8080/swagger-ui/index.html

Swagger3 暴露的 JSON 接口

  • 浏览器访问 Swagger3 暴露的 JSON 接口:http://127.0.0.1:8080/v3/api-docs

参考教程