背景
现在多数的项目开发采用前后端分离的方式,网站和移动端都需要进行数据交互和对接,这少不了使用 REST 编写 API 接口这种场景。特别是不同开发小组协作时,就更需要以规范和文档作为标准和协作基础。良好的文档可以减少沟通成本,达到事半功倍的效果 。
前端经常抱怨后端给的接口文档与实际情况不一致。后端又觉得编写及维护接口文档会耗费不少精力,经常来不及更新。其实无论是前端调用后端,还是后端调用后端,都期望有一个好的接口文档。但是这个接口文档对于程序员来说,就跟注释一样,经常会抱怨别人写的代码没有写注释,然而自己写起代码起来,最讨厌的,也是写注释。
发现了痛点就要去找解决方案。解决方案用的人多了,就成了标准的规范,这就是 Swagger 的由来。通过这套规范,你只需要按照它的规范去定义接口及接口相关的信息。再通过 Swagger 衍生出来的一系列项目和工具,就可以做到生成各种格式的接口文档,生成多种语言的客户端和服务端的代码,以及在线接口调试页面等等。在开发新版本或者迭代版本的时候,只需要更新 Swagger 描述文件,就可以自动生成接口文档和客户端服务端代码,做到调用端代码、服务端代码以及接口文档的一致性。
什么是 Swagger
官方网址:https://swagger.io/
简介
Swagger 是一个规范和完整的框架,用于生成、描述、调用和可视化 RESTful 风格的 Web 服务。是一套流行的 API 框架,可以帮助开发人员快速构建 API 文档,还可以方便测试项目各项功能。
API 的两层意思
帮助文档 JDK API
JDK:Java Development Kit 。
API:Application Programming Interface 。
应用程序接口 第三方支付支付宝接口
Swagger2 的特点
Swagger 是最流行的 API 开发工具,它遵循 OpenAPI Specification
Swagger 可以贯穿于整个 API 生态,如 API 的设计、编写 API 文档、测试和部署。
Swagger 是一种通用的,和编程语言无关的 API 描述规范。
Swagger 工具
使用流程
Swagger2 常用注解
@Api:修饰整个类,描述 Controller 的作用
@ApiOperation:描述一个类的一个方法,或者说一个接口
@ApiParam:单个参数描述
@ApiModel:用对象来接收参数
@ApiProperty:用对象接收参数时,描述对象的一个字段
@ApiResponse:HTTP 响应其中 1 个描述
@ApiResponses:HTTP 响应整体描述
@ApiIgnore:使用该注解忽略这个 API
@ApiError :发生错误返回的信息
@ApiImplicitParam:一个请求参数
@ApiImplicitParams:多个请求参数 Xxx
RESTful
REST 实际上为 Representational State Transfer 的缩写,翻译为“表现层状态转化” 。如果一个架构符合 REST 原则,就称它为 RESTful 架构。
实际上,“表现层状态转化”省略了主语,完整的说应该是“资源表现层状态转化”。 什么是资源(Resource)?资源指的是网络中信息的表现形式,比如一段文本,一首歌,一个视频文件等等;什么是表现层(Reresentational)?表现层即资源的展现在你面前的形式,比如文本可以是 JSON 格式的,也可以是 XML 形式的,甚至为二进制形式的。图片可以是 gif,也可以是 PNG;什么是状态转换(State Transfer)?用户可使用 URL 通过 HTTP 协议来获取各种资源,HTTP 协议包含了一些操作资源的方法,比如:GET 用来获取资源, POST 用来新建资源 , PUT 用来更新资源, DELETE 用来删除资源, PATCH 用来更新资源的部分属性。通过这些 HTTP 协议的方法来操作资源的过程即为状态转换。
下面对比下传统 URL 请求和 RESTful 风格请求的区别
从上面这张表,我们大致可以总结下传统请求和 RESTful 请求的几个区别:
传统请求通过 URL 来描述行为,如 create,delete 等;RESTful 请求通过 URL 来描述资源。
RESTful 请求通过 HTTP 请求的方法来描述行为,比如 DELETE,POST,PUT 等,并且使用 HTTP 状态码来表示不同的结果。
RESTful 请求通过 JSON 来交换数据。
Spring Boot 整合 Swagger2 构建 RESTful API
创建一个 Spring Boot 项目
添加 Swagger 依赖
<!--swagger2依赖-->
<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>
在 config 包下添加配置类
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import springfox.documentation.builders.ApiInfoBuilder;
import springfox.documentation.builders.PathSelectors;
import springfox.documentation.builders.RequestHandlerSelectors;
import springfox.documentation.service.ApiInfo;
import springfox.documentation.service.Contact;
import springfox.documentation.spi.DocumentationType;
import springfox.documentation.spring.web.plugins.Docket;
import springfox.documentation.swagger2.annotations.EnableSwagger2;
@Configuration
@EnableSwagger2
public class SwaggerConfig {
@Bean
public Docket buildDocket() {
return new Docket(DocumentationType.SWAGGER_2)
.groupName("test")
.apiInfo(buildApiInf())
.select()
.apis(RequestHandlerSelectors.basePackage("cn.wlh.demo.controller"))
.paths(PathSelectors.any())
.build();
}
private ApiInfo buildApiInf() {
return new ApiInfoBuilder()
.title("xxx系统 RESTful API 文档")
.description("xxx系统 RESTful API 文档")
.contact(new Contact("wlh", "http://www.xxx.cn", "37028121@qq.com"))
.version("1.0")
.build();
}
}
RESTful API 接口
Spring Boot 中包含了一些注解,对应于 HTTP 协议中的方法:
@GetMapping 对应 HTTP 中的 GET 方法;
@PostMapping 对应 HTTP 中的 POST 方法;
@PutMapping 对应 HTTP 中的 PUT 方法;
@DeleteMapping 对应 HTTP 中的 DELETE 方法;
@PatchMapping 对应 HTTP 中的 PATCH 方法。
Swagger2 的常用注解
@Api:用在请求的类上,表示对类的说明
常用参数
tags="说明该类的作用,非空时将覆盖value的值" value="描述类的作用"
其他参数:
description 对api资源的描述,在1.5版本后不再支持
basePath 基本路径可以不配置,在1.5版本后不再支持
position 如果配置多个Api 想改变显示的顺序位置,在1.5版本后不再支持
produces 设置MIME类型列表(output),例:"application/json, application/xml",默认为空
consumes 设置MIME类型列表(input),例:"application/json, application/xml",默认为空
protocols 设置特定协议,例:http, https, ws, wss。
authorizations 获取授权列表(安全声明),如果未设置,则返回一个空的授权值。
hidden 默认为false, 配置为true 将在文档中隐藏
示例
@Api(tags="登录请求")
@Controller
@RequestMapping(value="/highPregnant")
public class LoginController {}
@ApiOperation:用在请求的方法上,说明方法的用途、作用
常用参数
value="说明方法的用途、作用" notes="方法的备注说明"
其他参数:
tags 操作标签,非空时将覆盖value的值
response 响应类型(即返回对象)
responseContainer 声明包装的响应容器(返回对象类型)。有效值为 "List", "Set" or "Map"。
responseReference 指定对响应类型的引用。将覆盖任何指定的response()类
httpMethod 指定HTTP方法,"GET", "HEAD", "POST", "PUT", "DELETE", "OPTIONS" and "PATCH"
position 如果配置多个Api 想改变显示的顺序位置,在1.5版本后不再支持
nickname 第三方工具唯一标识,默认为空
produces 设置MIME类型列表(output),例:"application/json, application/xml",默认为空
consumes 设置MIME类型列表(input),例:"application/json, application/xml",默认为空
protocols 设置特定协议,例:http, https, ws, wss。
authorizations 获取授权列表(安全声明),如果未设置,则返回一个空的授权值。
hidden 默认为false, 配置为true 将在文档中隐藏
responseHeaders 响应头列表 code 响应的HTTP状态代码。默认 200
extensions 扩展属性列表数组
示例
@ResponseBody
@PostMapping(value="/login")
@ApiOperation(value = "登录检测", notes="根据用户名、密码判断该用户是否存在")
public UserModel login(@RequestParam(value = "name", required = false) String account,
@RequestParam(value = "pass", required = false) String password){}
@ApiImplicitParams:用在请求的方法上,表示一组参数说明
@ApiImplicitParam:用在@ApiImplicitParams注解中,指定一个请求参数的各个方面
name:参数名,参数名称可以覆盖方法参数名称,路径参数必须与方法参数一致
value:参数的汉字说明、解释
required:参数是否必须传,默认为false [路径参数必填]
paramType:参数放在哪个地方
· header --> 请求参数的获取:@RequestHeader
· query --> 请求参数的获取:@RequestParam
· path(用于restful接口)--> 请求参数的获取:@PathVariable
· body(不常用)
· form(不常用)
dataType:参数类型,默认String,其它值dataType="Integer"
defaultValue:参数的默认值
示例
@ResponseBody
@PostMapping(value="/login")
@ApiOperation(value = "登录检测", notes="根据用户名、密码判断该用户是否存在")
@ApiImplicitParams({ @ApiImplicitParam(name = "name", value = "用户名", required = false, paramType = "query", dataType = "String"),
@ApiImplicitParam(name = "pass", value = "密码", required = false, paramType = "query", dataType = "String") })
public UserModel login(@RequestParam(value = "name", required = false) String account,
@RequestParam(value = "pass", required = false) String password){}
@ApiResponses:用在请求的方法上,表示一组响应
@ApiResponse:用在@ApiResponses中,一般用于表达一个错误的响应信息
code:数字,例如400
message:信息,例如"请求参数没填好"
response:抛出异常的类
示例
@ResponseBody
@PostMapping(value="/update/{id}")
@ApiOperation(value = "修改用户信息",notes = "打开页面并修改指定用户信息") @ApiResponses({@ApiResponse(code=400,message="请求参数没填好"), @ApiResponse(code=404,message="请求路径没有或页面跳转路径不对") })
public JsonResult update(@PathVariable String id, UserModel model){}
@ApiParam: 用在请求方法中,描述参数信息
name:参数名称,参数名称可以覆盖方法参数名称,路径参数必须与方法参数一致
value:参数的简要说明。
defaultValue:参数默认值
required 属性是否必填,默认为false [路径参数必须填]
其他
allowableValues 限制参数的可接受值。1.以逗号分隔的列表 2、范围值 3、设置最小值/最大值
access 允许从API文档中过滤参数。
allowMultiple 指定参数是否可以通过具有多个事件接受多个值,默认为false
hidden 隐藏参数列表中的参数。
example 单个示例
examples 参数示例。仅适用于BodyParameters
示例
@ResponseBody
@PostMapping(value="/login")
@ApiOperation(value = "登录检测", notes="根据用户名、密码判断该用户是否存在")
public UserModel login(@ApiParam(name = "name", value = "用户名", required = false) @RequestParam(value = "name", required = false) String account, @ApiParam(name = "pass", value = "密码", required = false) @RequestParam(value = "pass", required = false) String password){}
或以实体类为参数
@ResponseBody
@PostMapping(value="/login")
@ApiOperation(value = "登录检测", notes="根据用户名、密码判断该用户是否存在")
public UserModel login(@ApiParam(name = "model", value = "用户信息Model") UserModel model){}
启动项目,访问 http://localhost:8080/swagger-ui.html 即可看到 Swagger 给我们生成的 API 页面:
Swagger3访问路径:http://localhost:8080/swagger-ui/
拓展:其他皮肤
我们可以导入不同的包实现不同的皮肤定义:
默认的 访问 http://localhost:8080/swagger-ui.html
<dependency>
<groupId>io.springfox</groupId>
<artifactId>springfox-swagger-ui</artifactId>
<version>2.9.2</version>
</dependency>
bootstrap-ui 访问 http://localhost:8080/doc.html
<!-- 引入swagger-bootstrap-ui包 /doc.html-->
<dependency>
<groupId>com.github.xiaoymin</groupId>
<artifactId>swagger-bootstrap-ui</artifactId>
<version>1.9.1</version>
</dependency>
Layui-ui 访问 http://localhost:8080/docs.html
<!-- 引入swagger-ui-layer包 /docs.html-->
<dependency>
<groupId>com.github.caspar-chen</groupId>
<artifactId>swagger-ui-layer</artifactId>
<version>1.1.3</version>
</dependency>
mg-ui 访问 http://localhost:8080/document.html
<!-- 引入swagger-ui-layer包 /document.html-->
<dependency>
<groupId>com.zyplayer</groupId>
<artifactId>swagger-mg-ui</artifactId>
<version>1.0.6</version>
</dependency>