框架--Swagger
引言
在现代前后端分离开发模式中,接口文档是团队协作的基石。然而,文档更新滞后、内容不规范等问题常导致开发效率低下。Swagger 作为一套开源工具集,能动态生成实时接口文档,解决这一痛点。本文将深入解析 Swagger 的核心原理、工具链及实践应用,帮助开发者高效集成和使用。
一、Swagger 核心概念
1. Swagger 简介
Swagger 是一套规范且完整的框架,专为生成、描述、调用和可视化 RESTful Web 服务设计。其核心价值在于:
- 动态文档生成:自动根据代码更新接口文档,避免人工维护的滞后性。
- 可视化测试:提供交互式 UI,支持直接测试 API 功能。
- 标准化输出:确保文档格式统一,提升团队协作效率。
例如,在微服务架构中,Swagger 能统一管理多个服务的 API,减少沟通成本。
2. Open API 规范(OAS)
Open API 规范是 REST API 的描述标准,此前称为 Swagger 规范。它定义了 API 的完整结构:
- 请求类型:如 GET、POST。
- 参数信息:输入/输出参数格式。
- 认证方法:OAuth2、API Key 等。
- 元数据:API 版本、团队信息等。
OAS 支持 YAML 或 JSON 格式,便于机器解析和人工阅读。示例 YAML 片段:
openapi: 3.0.0
info:title: 用户管理 APIversion: 1.0.0
paths:/users:get:summary: 获取用户列表responses:'200':description: 成功返回用户列表
3. Swagger 与 Open API 的关系
Swagger 是围绕 Open API 规范构建的一套开源工具集,可助力开发人员完成 REST API 的设计、构建、记录和使用工作。其包含的主要组件如下:
- Swagger Editor:基于浏览器的编辑器,支持实时预览和编辑 OAS 文件。
- Swagger UI:将 OAS 文件渲染为交互式文档,开发者可直接测试接口。
- Swagger Codegen:根据 OAS 生成客户端和服务端代码(如 Java、Python)。
- Swagger Inspector:高级调试工具,保存请求历史便于分析。
- Swagger Hub:云端平台,集成设计、文档生成和代码生成功能。
这些工具协同工作,形成“设计→实现→测试”闭环,提升开发效率 30% 以上。
二、Springfox 集成实战(通过Springfox使用Swagger)
在使用 Swagger 过程中,若遇到版本更新,仅需修改 Swagger 的描述文件即可。但在项目版本频繁更新的场景下,许多开发人员认为即便修改描述文件(yml 或 json)也会增加工作负担,久而久之便只修改代码,而不再更新描述文件,这使得基于描述文件生成的接口文档失去了实际意义。
鉴于 Spring 框架的广泛流行,Marty Pitt 编写了基于 Spring 的组件 swagger-springmvc,Spring-fox 便是在该组件基础上发展而来的全新项目。Spring-fox 能够根据代码自动生成接口文档,在项目版本更新时,开发人员只需正常修改代码,无需额外修改描述文件。Springfox 借助自身的 AOP 特性集成了 Swagger,其底层依然基于 Swagger,但使用起来更加便捷,因此在实际开发中,开发人员通常会直接使用 Spring-fox。Spring-fox 官网地址为:https://github.com/springfox/springfox
Springfox 是基于 Spring 的 Swagger 实现,通过 AOP 自动扫描代码生成文档。以下以 Spring Boot 项目为例,逐步演示集成过程。
1. 创建 Spring Boot 项目
在项目的 controller 层中,需创建一个 Handler(处理器)用于测试项目,确保程序能够正常运行。示例代码如下:
@RestController
@RequestMapping("/people")
public class DemoController {@RequestMapping("/getPeople")public People getPeople(Long id, String name) {People peo = new People();peo.setId(id);peo.setName(name);peo.setAddress("海淀");return peo;}
}
2. 添加 Springfox 依赖
在 pom.xml
中引入依赖(推荐使用最新版本):
<dependency><groupId>io.springfox</groupId><artifactId>springfox-swagger2</artifactId><version>3.0.0</version>
</dependency>
<dependency><groupId>io.springfox</groupId><artifactId>springfox-swagger-ui</artifactId><version>3.0.0</version>
</dependency>
3. 启用 Swagger
在启动类添加注解
在 SpringBoot 的启动类中添加 @EnableSwagger2 注解,添加该注解后,Spring-fox 会对当前项目中所有的控制器进行扫描,并应用 Swagger2 功能。示例代码如下:
@SpringBootApplication
@EnableSwagger2
public class MyApp {public static void main(String[] args) {SpringApplication.run(MyApp.class, args);}
}
4. 访问 Swagger UI
启动项目后,访问 http://localhost:8080/swagger-ui.html
:
- 页面展示所有控制器(如
UserController
)。 - 点击接口可查看详细参数和响应模型。
- 使用 "Try it out" 按钮直接测试 API。
三、Swagger UI 的使用和配置
通过自定义配置提升文档可读性和功能性。
1. 基础配置示例
创建 SwaggerConfig
类:
@Configuration
public class SwaggerConfig {@Beanpublic Docket getDocket() {return new Docket(DocumentationType.SWAGGER_2).apiInfo(swaggerDemoApiInfo()).select().build();}private ApiInfo swaggerDemoApiInfo() {return new ApiInfoBuilder().contact(new Contact("clx", "http://www.bjsxt.com", "xxx@163.com"))// 文档标题.title("这里是 Swagger 的标题")// 文档描述.description("这里是 Swagger 的描述")// 文档版本.version("1.0.0").build();}
}
2. 关键配置项解析
通过 apis () 方法可以指定项目中哪个包下的内容会被 Swagger 扫描并生成接口文档。示例代码如下:
@Bean
public Docket getDocket() {return new Docket(DocumentationType.SWAGGER_2).apiInfo(swaggerDemoApiInfo()).select().apis(RequestHandlerSelectors.basePackage("com.bjsxt.controller")).build();
}
3. 自定义注解排除不需要生成接口文档的方法
首先自定义一个注解,用于标记不需要生成接口文档的方法,示例代码如下:
@Target({ElementType.METHOD})
@Retention(RetentionPolicy.RUNTIME)
public @interface NotIncludeSwagger {
}
然后在 SwaggerConfig 配置类中添加相应规则,使得被该自定义注解标记的方法不被 Swagger 扫描生成接口文档。相关代码如下
@Bean
public Docket getDocket() {return new Docket(DocumentationType.SWAGGER_2).apiInfo(swaggerDemoApiInfo()).select().paths(allowPaths()).apis(not(withMethodAnnotation(NotIncludeSwagger.class))).build();
}
其中,not(withMethodAnnotation(NotIncludeSwagger.class))
表示排除被 @NotIncludeSwagger 注解标记的方法。
最后,在不需要生成接口文档的方法上添加 @NotIncludeSwagger 注解即可,示例代码如下:
@NotIncludeSwagger
@RequestMapping("/getPeople2")
public People getPeople2(Integer id, String name, String address) {People peo = new People();peo.setId(id);peo.setName(name);peo.setAddress(address);return peo;
}
四、Swagger2 常用注解
在使用 Swagger2 生成接口文档时,合理运用各种注解可以使文档更加规范、详细,便于开发人员理解和使用接口。以下是 Swagger2 中常用的注解及其用法:
(一)@Api
- 作用位置:类上。
- 作用:控制整个类生成接口信息的内容。
- 常用参数:
- tags:类的名称,可设置多个值,多个值表示对应多个副本。
- description:对类的描述信息。
代码示例:
@RestController
@RequestMapping("/people")
@Api(tags = {"mydemo"}, description = "描述")
public class DemoController {// 类中方法...
}
在 Swagger UI 页面中,该类对应的接口文档会显示 tags 中设置的名称 “mydemo” 以及 description 中的描述信息。
(二)@ApiOperation
- 作用位置:方法上。
- 作用:对方法进行总体描述,说明方法的功能等信息。
- 常用参数:
- value:接口的简要描述。
- notes:接口的补充提示信息。
代码示例:
@ApiOperation(value = "接口描述", notes = "接口提示信息")
@RequestMapping("/getPeople")
public People getPeople(Long id, String name) {// 方法逻辑...
}
在 Swagger UI 页面中,该方法对应的接口会显示 value 中的 “接口描述” 以及 notes 中的 “接口提示信息”,同时会展示请求方式(如 POST /getPeople)。
(三)@ApiParam
- 作用位置:方法参数前面。
- 作用:对参数进行描述,说明参数的含义、是否为必传项等信息。
- 常用参数:
- name:参数名称。
- value:参数的描述信息。
- required:表示该参数是否为必须传入的参数,布尔类型,true 表示必传,false 表示非必传。
代码示例:
public People getPeople(Integer id, @ApiParam(value = "姓名", required = true) String name, String address) {// 方法逻辑...
}
在 Swagger UI 页面中,该参数会显示 name 对应的 “姓名”、value 中的描述,且因 required 设为 true,会标注 “*required”,提示该参数为必传项。
(四)@ApiModel
- 作用位置:类上,主要应用于实体类(Model)。
- 作用:对实体类进行描述,说明该实体类的用途等信息。
- 常用参数:
- value:实体类的名称。
- description:对实体类的描述信息。
代码示例:
@ApiModel(value = "人类", description = "描述")
public class People {// 类中属性及方法...
}
在 Swagger UI 页面的 “Models” 板块中,会显示该实体类对应的 value “人类” 以及 description 中的描述信息。
(五)@ApiModelProperty
- 作用位置:方法或属性上,常用于实体类的属性上。
- 作用:对实体类的属性进行说明,包括属性含义、是否必传、示例值等信息。
- 常用参数:
- value:字段的说明信息。
- name:重写属性名,若不设置则使用属性本身的名称。
- required:表示该属性是否为必须的,布尔类型。
- example:属性的示例内容,便于开发人员了解参数格式。
- hidden:表示该属性是否在接口文档中隐藏,布尔类型,true 表示隐藏,false 表示显示。
代码示例:
@ApiModelProperty(value = "姓名", name = "name", required = true, example = "张三")
private String name;
在 Swagger UI 页面的实体类详情中,该属性会显示 value “姓名”、name “name”、example “张三”,且因 required 设为 true,会标注 “*”。
(六)@ApiIgnore
- 作用位置:方法、类或参数上。
- 作用:表示被该注解标记的方法、类或参数会被 Swagger 忽略,不生成对应的接口文档信息,与自定义注解 @NotIncludeSwagger 效果类似,但 @ApiIgnore 是 Swagger 内置注解。
代码示例:
@ApiIgnore
@RequestMapping("/getPeople3")
public People getPeople3(Integer id) {// 方法逻辑...
}
被 @ApiIgnore 注解标记的 getPeople3 方法不会在 Swagger UI 页面中显示。
(七)@ApiImplicitParam
- 作用位置:方法上。
- 作用:用于描述方法的单个请求参数,总体功能与 @ApiParam 类似,但 @ApiImplicitParam 是作用在方法上,而 @ApiParam 作用在参数上。
- 常用参数:
- value:对接口参数的简单必要描述。
- name:接口参数的名称。
- required:表示该参数是否为必须传入的,布尔类型。
- paramType:指定接口参数的位置,常用的位置有 header(请求头)、query(请求参数)、path(URL 路径)等。
- dataType:接口参数的数据类型。
代码示例:
@PostMapping("/getPeople")
@ApiImplicitParam(name = "address", value = "地址", required = true, paramType = "query", dataType = "string")
public People getPeople(Integer id, @ApiParam(value = "姓名", required = true) String name, String address) {// 方法逻辑...
}
在 Swagger UI 页面中,该参数会显示 name “address”、value “地址”、paramType “query”、dataType “string”,且因 required 设为 true,会标注 “*required”。
若方法需要配置多个参数,可使用 @ApiImplicitParams 注解,将多个 @ApiImplicitParam 注解作为其 value 值,示例代码如下:
@ApiImplicitParams(value = {@ApiImplicitParam(name = "id", value = "编号", required = true),@ApiImplicitParam(name = "name", value = "姓名", required = true)
})
@RequestMapping("/getPeople4")
public People getPeople4(Integer id, String name) {// 方法逻辑...
}