Swagger 基础

826 阅读7分钟

一、Swagger 简介

  • 官网地址

  • 前后端分离:

    • 前端:前端控制层、视图层;
    • 后端:后端控制层、服务层、数据访问层;
    • 前后端,通过 API 进行交互;
    • 前后端相对独立,且松耦合;
  • 产生的问题:

    • 前后端集成,需要 API 对接进行交互,就需要一个 API 规范文档,但文档不能根据代码的变化,实时动态的改变,当后端修改了接口,前端不能及时获取,导致调用出错,需要手动维护 API 文档,加大了开发的工作量和困难;
  • 解决方案:

    • Swagger 解决了这一系列的问题,通过定义 schema [ 计划的提纲 ],实时跟踪最新的 API,降低集成风险;
  • Swagger:

    • Restful Api 文档在线自动生成器:API 文档 与 API 定义同步更新;
    • 直接运行,在线测试 API;
    • 支持多种语言(如:Java、PHP 等);

二、Spring Boot 集成 Swagger

2.1 环境搭建

  • 新建 Spring Boot web 项目:
  • 导入相关依赖:
<!--SpringBoot整合swagger3方式-->
<dependency>
    <groupId>io.springfox</groupId>
    <artifactId>springfox-boot-starter</artifactId>
    <version>3.0.0</version>
</dependency>
  • 编写 Controller 测试,确保运行成功;

  • 创建配置文件:application.yaml

# Springfox使用的路径匹配是基于AntPathMatcher的,SpringBoot2.6.X使用的是PathPatternMatcher
spring:
  mvc:
    pathmatch:
      matching-strategy: ANT_PATH_MATCHER
  • 配置 Swagger:需要编写自定义配置类;

    • 新建配置目录:config;

    • 创建 SwaggerConfig;

// 配置类
@Configuration
// 开启Swagger2的自动配置
// @EnableSwagger2
// 开启Swagger3的自动配置
@EnableOpenApi
public class SwaggerConfig {
}
  • 运行测试:访问地址 http://localhost:8080/swagger-ui/index.html 与 2.x 访问地址 http://localhost:8080/swagger-ui.html 不同;

2.2 配置 Swagger

  • Swagger 实例 Bean 是 Docket,需要通过配置 Docket 实例,来配置Swaggger:
// 配置docket,以配置Swagger具体参数
@Bean
public Docket docket() {
    // 使用 OpenAPI 3.0 (OpenAPI Specification 的简称 OAS)
    return new Docket(DocumentationType.OAS_30);
}
  • 通过 ApiInfo 属性,配置文档信息:
// 配置ApiInfo文档信息
private ApiInfo apiInfo() {
    return new ApiInfoBuilder()
            // 文档标题
            .title("Swagger3.0的接口文档测试")
            // 文档描述
            .description("api信息列表")
            // 联系人信息
            .contact(new Contact("作者", "作者URL", "作者Email"))
            // 文档版本
            .version("V1.0")
            // 组织链接
            .termsOfServiceUrl("http://www.test.com")
            .build();
}
  • 在 Docket 实例关联上 apiInfo()
// 配置docket,以配置Swagger具体参数
@Bean
public Docket docket() {
    // 使用 OpenAPI 3.0 (OpenAPI Specification 的简称 OAS)
    return new Docket(DocumentationType.OAS_30)
        // 将api的元信息,设置为包含在json ResourceListing响应中
        .apiInfo(apiInfo());
}
  • 运行测试:

2.3 配置扫描接口

  • 构建 Docket 时,通过 select() 方法,配置扫描接口:
// 配置docket,以配置Swagger具体参数
@Bean
public Docket docket() {
    // 使用 OpenAPI 3.0 (OpenAPI Specification 的简称 OAS)
    return new Docket(DocumentationType.OAS_30)
            // 将api的元信息,设置为包含在json ResourceListing响应中
            .apiInfo(apiInfo())
            // .select():配置扫描接口
            .select()
            // apis:添加swagger接口提取范围 RequestHandlerSelectors:扫描接口方式
        	// .basePackage:指定要扫描的包
        	.apis(RequestHandlerSelectors.basePackage("com.study.controller"))
        	.build();
}
  • 其他扫描接口的方式:
// 扫描所有,项目中的所有接口都会被扫描到
any()
// 不扫描接口
none()
// 通过方法上的注解扫描,如withMethodAnnotation(GetMapping.class)只扫描get请求
withMethodAnnotation(final Class<? extends Annotation> annotation)
// 通过类上的注解扫描,如.withClassAnnotation(Controller.class)只扫描有controller注解的类中的接口
withClassAnnotation(final Class<? extends Annotation> annotation)
// 根据包路径扫描接口
basePackage(final String basePackage)
  • 通过 .paths() 配置接口扫描过滤:
// 配置docket,以配置Swagger具体参数
@Bean
public Docket docket() {
    // 使用 OpenAPI 3.0 (OpenAPI Specification 的简称 OAS)
    return new Docket(DocumentationType.OAS_30)
            // 将api的元信息,设置为包含在json ResourceListing响应中
            .apiInfo(apiInfo())
            // .select():配置扫描接口
            .select()
            // apis:添加swagger接口提取范围 RequestHandlerSelectors:扫描接口方式
        	// .basePackage:指定要扫描的包
        	.apis(RequestHandlerSelectors.basePackage("com.study.controller"))
        	// .paths():过滤路径
        	// 只扫描请求以/test开头的接口
            .paths(PathSelectors.ant("/test"))
        	.build();
}
  • 配置过滤的可选值:
// 任何请求都扫描
any()
// 任何请求都不扫描
none()
// 通过正则表达式控制
regex(final String pathRegex)
// 通过ant()控制
ant(final String antPattern)

2.4 配置开关 Swagger

  • 通过 enable() 方法,配置是否启用 Swagger,如果是 false,Swagger将不能在浏览器中访问:
// 配置docket,以配置Swagger具体参数
@Bean
public Docket docket() {
    // 使用 OpenAPI 3.0 (OpenAPI Specification 的简称 OAS)
    return new Docket(DocumentationType.OAS_30)
            // 将api的元信息,设置为包含在json ResourceListing响应中
            .apiInfo(apiInfo())
        	// 配置是否启用Swagger,如果是false,在浏览器将无法访问
        	.enable(false)
            // .select():配置扫描接口
            .select()
            // apis:添加swagger接口提取范围 RequestHandlerSelectors:扫描接口方式
        	// .basePackage:指定要扫描的包
        	.apis(RequestHandlerSelectors.basePackage("com.study.controller"))
        	// .paths():过滤路径
        	// 只扫描请求以/test开头的接口
            .paths(PathSelectors.ant("/test"))
        	.build();
}
  • 关闭 Swagger,运行测试:

  • 动态配置项目:test、dev 环境时,显示Swagger,prod 时不显示:

// 配置docket,以配置Swagger具体参数
@Bean
// Environment:获取环境设置
public Docket docket(Environment environment) {
    // 设置要显示Swagger的环境
    Profiles of = Profiles.of("dev", "test");
    // 判断当前是否处于该环境
    // 通过 enable() 接收此参数,判断是否要显示
    boolean flag = environment.acceptsProfiles(of);
    // 使用 OpenAPI 3.0 (OpenAPI Specification 的简称 OAS)
    return new Docket(DocumentationType.OAS_30)
            // 将api的元信息,设置为包含在json ResourceListing响应中
            .apiInfo(apiInfo())
        	// 配置是否启用Swagger,如果是false,在浏览器将无法访问
        	.enable(flag)
            // .select():配置扫描接口
            .select()
            // apis:添加swagger接口提取范围 RequestHandlerSelectors:扫描接口方式
        	// .basePackage:指定要扫描的包
        	.apis(RequestHandlerSelectors.basePackage("com.study.controller"))
        	// .paths():过滤路径
        	// 只扫描请求以/test开头的接口
            .paths(PathSelectors.ant("/test"))
        	.build();
}
  • 设置运行环境:application.properties
# 设置运行环境
spring.profiles.active=dev
  • 在项目中,增加一个 dev 的配置文件,测试效果;

2.5 配置 API 分组

  • 如果没有配置分组,默认是 default,通过 groupName() 方法,配置分组:
// 配置docket,以配置Swagger具体参数
@Bean
public Docket docket() {
    // 使用 OpenAPI 3.0 (OpenAPI Specification 的简称 OAS)
    return new Docket(DocumentationType.OAS_30)
            // 将api的元信息,设置为包含在json ResourceListing响应中
            .apiInfo(apiInfo())
            // 配置分组
            .groupName("测试组A")
            // 省略其它配置...
}
  • 配置多个分组,只需要配置多个 docket 即可:
// 配置多个分组
@Bean
public Docket docket2() {
    return new Docket(DocumentationType.OAS_30).groupName("测试组B");
}

@Bean
public Docket docket3() {
    return new Docket(DocumentationType.OAS_30).groupName("测试组C");
}

@Bean
public Docket docket4() {
    return new Docket(DocumentationType.OAS_30).groupName("测试组D");
}
  • 运行测试:

2.6 实体类配置

  • 新建实体类:
// @Schema 注解用在类上不生效,使用@ApiModel替代
// @ApiModel:实体类注释
@ApiModel("User 用户实体")
public class User {
    // @Schema:描述对象属性,在实体类属性上使用,等同于@ApiModelProperty
    @Schema(name = "用户名", description = "用户名")
    public String userName;
    @Schema(description = "密码")
    public String passWord;
    // get、set方法
}
  • 创建实例类请求接口:
    • 只要接口的返回值中,存在实体类(即使是泛型),都会被扫描到 Swagger 中;
@RestController
// @Tag:接口类描述,在Controller类上使用,等同于@Api
@Tag(name = "Hello控制类")
public class Hello {
    @GetMapping("/hello")
    public String hello() {
        return "hello swagger";
    }

    // 只要接口的返回值中,存在实体类,就会被扫描到Swagger中
    @PostMapping("/user")
    public User getUser() {
        return new User();
    }

    @GetMapping("/hello2")
    // @Operation:接口方法描述,在Controller方法上使用,等同于@ApiOperation
    @Operation(summary = "hello2 接口方法")
    // @Parameter:参数描述,在Controller 方法的参数上使用,等同于@ApiParam
    public String hello2(@Parameter(description = "用户名") String username) {
        return "Hello " + username;
    }
    
    @PostMapping("/h1")
    // @Operation:接口方法描述,在Controller方法上使用,等同于@ApiOperation
    @Operation(summary = "h1 接口方法")
    // @Parameter:参数描述,在Controller 方法的参数上使用,等同于@ApiParam
    public User h1(@Parameter(description = "用户") User user) {
        return user;
    }
}
  • 运行测试:主页面

  • 查看 GET 请求:

  • 查看 POST 请求:

  • 实体类描述:

  • 注:并不是因为 @ApiModel 等注解,让实体显示在这里,而是,只要出现在接口方法的返回值上的实体,都会显示在这里,这些注解,只是实现了注释功能;

2.7 常用注解

  • Swagger2 常用注解说明:
    • @Api:用在 controller 类,描述 API 接口;
    • @ApiOperation:描述接口方法
    • @ApiModel:描述对象
    • @ApiModelProperty:描述对象属性
    • @ApiImplicitParams:描述接口参数
    • @ApiResponses:描述接口响应
    • @ApiIgnore:忽略接口方法
  • Swagger3 与 Swagger2 注解对比使用:
    • Swagger2 io.swagger.annotations 包下;
    • Swagger3 定义在 io.swagger.v3.oas.annotations 包下;
    • Springdoc 官网
swagger2OpenAPI 3注解位置
@Api@Tag(name = “接口类描述”)Controller 类上
@ApiOperation@Operation(summary =“接口方法描述”)Controller 方法上
@ApiImplicitParams@ParametersController 方法上
@ApiImplicitParam@Parameter(description=“参数描述”)Controller 方法上 @Parameters
@ApiParam@Parameter(description=“参数描述”)Controller 方法的参数上
@ApiIgnore@Parameter(hidden = true)@Operation(hidden = true)@Hidden排除或隐藏 api
@ApiModel@SchemaDTO 类上
@ApiModelProperty@SchemaDTO 属性上

总结:

  • 可以通过 Swagger 给一些比较难理解的属性和接口,增加注释信息;
  • 接口文档实时更新;
  • 可以在线测试;
  • 注意:在正式发布时,需要关闭 Swagger,出于安全考虑,可以节省内存;