今天技术总监说:小明,咱们本次3.0改造,使用swagger2.0做为先后端分离的接口规范,它能够一键生成先后端的API,一劳永逸……小明:???html
Spring Boot 框架是目前很是流行的微服务框架,咱们不少状况下使用它来提供 Rest API,而对于 Rest API 来讲很重要的一部份内容就是文档,Swagger 为咱们提供了一套经过代码和注解自动生成文档的方法,这一点对于保证 API 文档的及时性将有很大的帮助。本文将使用 Swagger 2 规范的 Springfox 实现来了解如何在 Spring Boot 项目中使用 Swagger,主要包含了如何使用 Swagger 自动生成文档、使用 Swagger 文档以及 Swagger 相关的一些高级配置和注解。前端
Swagger 是一套基于 OpenAPI 规范构建的开源工具,能够帮助咱们设计、构建、记录以及使用 Rest API。Swagger 主要包含了如下三个部分:java
当下不少公司都采起先后端分离的开发模式,前端和后端的工做由不一样的工程师完成。在这种开发模式下,维持一份及时更新且完整的 Rest API 文档将会极大的提升咱们的工做效率。传统意义上的文档都是后端开发人员手动编写的,相信你们也都知道这种方式很难保证文档的及时性,这种文档长此以往也就会失去其参考意义,反而还会加大咱们的沟通成本。而 Swagger 给咱们提供了一个全新的维护 API 文档的方式,下面咱们就来了解一下它的优势:git
Swagger UI 呈现出来的是一份可交互式的 API 文档,咱们能够直接在文档页面尝试 API 的调用,省去了准备复杂的调用参数的过程。程序员
还能够将文档规范导入相关的工具(例如 SoapUI), 这些工具将会为咱们自动地建立自动化测试。github
以上这些优势足以说明咱们为何要使用 Swagger 了,您是否已经对 Swagger 产生了浓厚的兴趣了呢?下面咱们就将一步一步地在 Spring Boot 项目中集成和使用 Swagger,让咱们从准备一个 Spring Boot 的 Web 项目开始吧。web
在这一步咱们将准备一个基础的 Spring Boot 的 Web 项目,而且提供后面所须要的全部 API。spring
您能够经过 Spring Initializr 页面生成一个空的 Spring Boot 项目,固然也能够下载 springboot-pom.xml 文件,而后使用 Maven 构建一个 Spring Boot 项目。项目建立完成后,为了方便后面代码的编写您能够将其导入到您喜欢的 IDE 中,我这里选择了 Intelli IDEA 打开。apache
因为建立的是一个 Web 项目,因此咱们须要依赖 Spring Boot 的 Web 组件,只须要在 pom.xml 增长以下内容便可:后端
清单 1. 添加 Web 依赖
<dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-web</artifactId> </dependency>
清单 2. UserController.java 代码
@RestController @RequestMapping("/user") public class UserController { @PostMapping("/add") public boolean addUser(@RequestBody User user) { return false; } @GetMapping("/find/{id}") public User findById(@PathVariable("id") int id) { return new User(); } @PutMapping("/update") public boolean update(@RequestBody User user) { return true; } @DeleteMapping("/delete/{id}") public boolean delete(@PathVariable("id") int id) { return true; } }
通过上面的步骤,咱们已经拥有了五个接口,分别是:
下面咱们将经过集成 Swagger2,而后为这 5 个 Rest API 自动生成接口文档。
首先要作的天然是添加 Swagger2 所须要的依赖包:
清单 3. 添加 Swagger 依赖
<dependency> <groupId>io.springfox</groupId> <artifactId>springfox-swagger2</artifactId> <version>2.9.2</version> </dependency>
Springfox 提供了一个 Docket 对象,让咱们能够灵活的配置 Swagger 的各项属性。下面咱们新建一个 cn.itweknow.sbswagger.conf.SwaggerConfig.java 类,并增长以下内容:
清单 4. Swagger Java 配置
@Configuration @EnableSwagger2 public class SwaggerConfig { @Bean public Docket api() { return new Docket(DocumentationType.SWAGGER_2) .select() .apis(RequestHandlerSelectors.any()) .paths(PathSelectors.any()) .build(); } }
注意: @Configuration 是告诉 Spring Boot 须要加载这个配置类,@EnableSwagger2 是启用 Swagger2,若是没加的话天然而然也就看不到后面的验证效果了。
至此,咱们已经成功的在 Spring Boot 项目中集成了 Swagger2,启动项目后,咱们能够经过在浏览器中访问 http://localhost:8080/ v2/api-docs 来验证,您会发现返回的结果是一段 JSON 串,可读性很是差。幸运的是 Swagger2 为咱们提供了可视化的交互界面 SwaggerUI,下面咱们就一块儿来试试吧。
和以前同样,集成的第一步就是添加相关依赖,在 pom.xml 中添加以下内容便可:
清单 5. 添加 Swagger UI 依赖
<dependency> <groupId>io.springfox</groupId> <artifactId>springfox-swagger-ui</artifactId> <version>2.9.2</version> </dependency>
其实就只须要添加一下依赖就能够了,咱们从新启动一下项目,而后在浏览器中访问 http://localhost:8080/swagger-ui.html 就能够看到以下的效果了:
图 1. Swagger UI
点击查看大图
能够看到虽然可读性好了一些,但对接口的表述还不是那么的清楚,接下来咱们就经过一些高级配置,让这份文档变的更加的易读。
清单 6. 给 Controller 添加描述信息
@Api(tags = "用户相关接口", description = "提供用户相关的 Rest API") public class UserController
清单 7. 给接口添加描述信息
@ApiOperation("新增用户接口") @PostMapping("/add") public boolean addUser(@RequestBody User user) { return false; }
清单 8. 给实体类添加描述信息
@ApiModel("用户实体") public class User { @ApiModelProperty("用户 id") private int id; }
清单 9. 配置文档信息
@Bean public Docket api() { return new Docket(DocumentationType.SWAGGER_2) .select() .apis(RequestHandlerSelectors.any()) .paths(PathSelectors.any()) .build() .apiInfo(apiInfo()); } private ApiInfo apiInfo() { return new ApiInfo( "Spring Boot 项目集成 Swagger 实例文档", "个人博客网站:https://itweknow.cn,欢迎你们访问。", "API V1.0", "Terms of service", new Contact("名字想好没", "https://itweknow.cn", "gancy.programmer@gmail.com"), "Apache", "http://www.apache.org/", Collections.emptyList()); }
通过上面的步骤,咱们的文档将会变成下图的样子,如今看起来就清楚不少了。
图 2. 补全信息后的 Swagger 文档界面
点击查看大图
有些时候咱们并非但愿全部的 Rest API 都呈如今文档上,这种状况下 Swagger2 提供给咱们了两种方式配置,一种是基于 @ApiIgnore 注解,另外一种是在 Docket 上增长筛选。
若是想在文档中屏蔽掉删除用户的接口(user/delete),那么只须要在删除用户的方法上加上 @ApiIgnore 便可。
清单 10. @ApiIgnore 使用实例
@ApiIgnore public boolean delete(@PathVariable("id") int id)
apis():这种方式咱们能够经过指定包名的方式,让 Swagger 只去某些包下面扫描。
paths():这种方式能够经过筛选 API 的 url 来进行过滤。
在集成 Swagger2 的章节中咱们这两个方法指定的都是扫描全部,没有指定任何过滤条件。若是咱们在咱们修改以前定义的 Docket 对象的 apis() 方法和 paths() 方法为下面的内容,那么接口文档将只会展现 /user/add 和 /user/find/{id} 两个接口。
清单 11. 使用 Docket 配置接口筛选
.apis(RequestHandlerSelectors.basePackage("cn.itweknow.sbswagger.controller")) .paths(Predicates.or(PathSelectors.ant("/user/add"), PathSelectors.ant("/user/find/*")))
图 3. 通过筛选事后的 Swagger 文档界面
点击查看大图
Swagger 容许咱们经过 Docket 的 globalResponseMessage() 方法全局覆盖 HTTP 方法的响应消息,可是首先咱们得经过 Docket 的 useDefaultResponseMessages 方法告诉 Swagger 不使用默认的 HTTP 响应消息,假设咱们如今须要覆盖全部 GET 方法的 500 和 403 错误的响应消息,咱们只须要在 SwaggerConfig.java 类中的 Docket Bean 下添加以下内容:
清单 12. 自定义响应消息
.useDefaultResponseMessages(false) .globalResponseMessage(RequestMethod.GET, newArrayList( new ResponseMessageBuilder() .code(500) .message("服务器发生异常") .responseModel(new ModelRef("Error")) .build(), new ResponseMessageBuilder() .code(403) .message("资源不可用") .build() ));
添加如上面的代码后,以下图所示,您会发如今 SwaggerUI 页面展现的全部 GET 类型请求的 403 以及 500 错误的响应消息都变成了咱们自定义的内容。
图 4. 自定义响应消息
点击查看大图
SwaggerUI 会以列表的方式展现全部扫描到的接口,初始状态是收缩的,咱们只须要点击展开就好,并且会在左边标识接口的请求方式(GET、POST、PUT、DELETE 等等)。
图 5. Swagger 接口列表界面
点击查看大图
以下图所示,点击接口展开后页面右上角的 Try it out 按钮后,页面会变成如图所示:
图 6. 接口详情界面
点击查看大图
SwaggerUI 会给咱们自动填充请求参数的数据结构,咱们须要作的只是点击 Execute 便可发起调用
图 7. 接口调用界面
点击查看大图
以下图所示,SwaggerUI 会经过咱们在实体上使用的 @ApiModel 注解以及@ApiModelProperty 注解来自动补充实体以及其属性的描述和备注。
图 8. 实体界面
点击查看大图
在本章节中我将给出一些 Swagger 中经常使用的注解以及其经常使用的属性,并对其一一解释,方便您查看。
@Api: 可设置对控制器的描述。
表 1. @Api 主要属性
|注解属性 |类型 |描述|
| ------|--------|
|tags |String[] |控制器标签。|
|description |String |控制器描述(该字段被申明为过时)。|
表 2. @ApiOperation 主要属性
|注解属性 |类型 |描述|
| ------|--------|
|value| String| 接口说明。|
|notes |String |接口发布说明。|
|tags |Stirng[]| 标签。|
|response |Class<?>| 接口返回类型。|
|httpMethod| String| 接口请求方式。|
@ApiIgnore: Swagger 文档不会显示拥有该注解的接口。
@ApiImplicitParams: 用于描述接口的非对象参数集。
@ApiImplicitParam: 用于描述接口的非对象参数,通常与 @ApiImplicitParams 组合使用。
表 3. @ApiImplicitParam 主要属性
注解属性 | 描述 |
---|---|
paramType | 查询参数类型,实际上就是参数放在那里。取值:
|
dataType | 参数的数据类型。取值:
|
name | 参数名字。 |
value | 参数意义的描述。 |
required | 是否必填。取值:
|
表 4. @ApiModelProperty 主要属性
|注解属性| 类型| 描述|
|-------|-------|------|
|value |String| 字段说明。|
|name |String |重写字段名称。|
|dataType| Stirng| 重写字段类型。|
|required |boolean| 是否必填。|
|example |Stirng| 举例说明。|
|hidden |boolean |是否在文档中隐藏该字段。|
|allowEmptyValue| boolean |是否容许为空。|
|allowableValues| String |该字段容许的值,当咱们 API 的某个参数为枚举类型时,使用这个属性就能够清楚地告诉 API 使用者该参数所能容许传入的值。|
在本教程中,咱们学会了如何使用 Swagger 2 来生成 Spring Boot REST API 的文档。咱们还研究了如何过滤 API、自定义 HTTP 响应消息以及如何使用 SwaggerUI 直接调用咱们的 API。您能够在 Github 上找到本教程的完整实现,这是一个基于 IntelliJ IDEA 的项目,所以它应该很容易导入和运行,固然若是您想对本教程作补充的话欢迎发邮件给我 (mynamecoder@163.com) 或者直接在 GitHub 上提交 Pull Request。
Spring 指南
Spring 主页
Spring Boot 参考指南
Swagger 主页
本文源码地址