前言
本篇博客是本人在网上学习Swagger所产出的个人笔记。主要内容有:
1.Swagger的安装
2.Swagger的介绍
3.Swagger2中常用的注解
4.快速上手案例
准备工作:Swagger Editor安装与启动
- 1.下载Swagger-Editor。直接下载zip文件地址并解压
- 下载zip文件网址: https://swagger.io/download-page/**
- 2.下载并且安装node.js
- 3.npm install -g http-server
- 4.进入swagger-editor文件夹。运行http-server命令。
- 5.在浏览器中输入http://127.0.0.1:8080即可看到Swagger-Editor的界面(看到如下图就说名OK了)
1.什么是 Swagger
Swagger 是一系列 RESTful API 的工具,通过 Swagger 可以获得项目的一种交互式文档,客户端 SDK 的自动生成等功能。
Swagger 的目标是为 REST APIs 定义一个标准的、与语言无关的接口,使人和计算机在看不到源码或者看不到文档或者不能通过网络流量检测的情况下,能发现和理解各种服务的功能。当服务通过 Swagger 定义,消费者就能与远程的服务互动通过少量的实现逻辑。类似于低级编程接口,Swagger 去掉了调用服务时的很多猜测。
Swagger(丝袜哥)是世界上最流行的 API 表达工具。
Swagger 是一个简单但功能强大的 API 表达工具。它具有地球上最大的 API 工具生态系统,数以千计的开发人员,使用几乎所有的现代编程语言,都在支持和使用 Swagger。使用 Swagger 生成 API,我们可以得到交互式文档,自动生成代码的 SDK 以及 API 的发现特性等。
使用 Spring Boot 集成 Swagger 的理念是,使用注解来标记出需要在 API 文档中展示的信息,Swagger 会根据项目中标记的注解来生成对应的 API 文档。Swagger 被号称世界上最流行的 API 工具,它提供了 API 管理的全套解决方案,API 文档管理需要考虑的因素基本都包含,这里将讲解最常用的定制内容。
2.Swagger常用注解
Swagger 通过注解表明该接口会生成文档,包括接口名、请求方法、参数、返回信息等,常用注解内容如下:
作用范围 | API | 使用位置 |
---|---|---|
协议集描述 | @Api | 用于 Controller 类上 |
协议描述 | @ApiOperation | 用在 Controller 的方法上 |
非对象参数集 | @ApiImplicitParams | 用在 Controller 的方法上 |
非对象参数描述 | @ApiImplicitParam | 用在 @ApiImplicitParams 的方法里边 |
响应集 | @ApiResponses | 用在 Controller 的方法上 |
响应信息参数 | @ApiResponse | 用在 @ApiResponses 里边 |
描述返回对象的意义 | @ApiModel | 用在返回对象类上 |
对象属性 | @ApiModelProperty | 用在出入参数对象的字段上 |
@Api 的使用
Api 作用在 Controller 类上,做为 Swagger 文档资源,该注解将一个 Controller(Class)标注为一个 Swagger 资源(API)。在默认情况下,Swagger-Core 只会扫描解析具有 @Api 注解的类,而会自动忽略其他类别资源(JAX-RS endpoints、Servlets 等)的注解。
使用示例:
@Api(value = "测试",description = "swaggerAPI测试",position = 100,protocols = "http")
@RestController
@RequestMapping("/")
public class TestController {
}
与 Controller 注解并列使用,属性配置如表所示:
属性名称 | 备注 |
---|---|
value | url 的路径值 |
tags | 如果设置这个值,value 的值会被覆盖 |
description | 对 API 资源的描述 |
produces | For example, “application/json, application/xml” |
consumes | For example, “application/json, application/xml” |
protocols | Possible values: http, https, ws, wss |
authorizations | 高级特性认证时配置 |
hidden | 配置为 true 将在文档中隐藏 |
ApiOperation 的使用
ApiOperation 定义在方法上,描述方法名、方法解释、返回信息、标记等信息。
使用示例:
@ApiOperation(value = "消息列表",notes = "完整的消息内容列表",produces="application/json, application/xml",consumes="application/json, application/xml",response = List.class)
@GetMapping(value = "messages")
public List<Message> list() {
}
属性名称 | 备注 |
---|---|
value | url 的路径值 |
tags | 如果设置这个值、value的 值会被覆盖 |
produces | For example, “application/json, application/xml” |
consumes | For example, “application/json, application/xml” |
protocols | Possible values: http, https, ws, wss |
authorizations | 高级特性认证时配置 |
hidden | 配置为 true 将在文档中隐藏 |
response | 返回的对象 |
responseContainer | 这些对象是有效的 “List”, “Set” or “Map”,其他无效 |
httpMethod | “GET”、“HEAD”、“POST”、“PUT”、“DELETE”、“OPTIONS” and “PATCH” |
code | http 的状态码 默认 200 |
extensions | 扩展属性 |
@ApiImplicitParams 和 @ApiImplicitParam 的使用
@ApiImplicitParams 用于描述方法的返回信息,和 @ApiImplicitParam 注解配合使用;@ApiImplicitParam 用来描述具体某一个参数的信息,包括参数的名称、类型、限制等信息。
使用示例:
@ApiOperation(value = "添加消息", notes = "根据参数创建消息")@ApiImplicitParams({@ApiImplicitParam(name = "id", value = "消息 ID", required = true, dataType = "Long", paramType = "query"),@ApiImplicitParam(name = "text", value = "正文", required = true, dataType = "String", paramType = "query"),@ApiImplicitParam(name = "summary", value = "摘要", required = false, dataType = "String", paramType = "query"),
})
@PostMapping(value = "message")
public Message create(Message message) {
}
属性名称 | 备注 |
---|---|
name | 接收参数名 |
value | 接收参数的意义描述 |
required | 参数是否必填值为 true 或者 false |
dataType | 参数的数据类型只作为标志说明,并没有实际验证 |
paramType | 查询参数类型,其值: path 以地址的形式提交数据 query 直接跟参数完成自动映射赋 body 以流的形式提交,仅支持 POST header 参数在 request headers 里边提交 form 以 form 表单的形式提交 仅支持 POST |
defaultValue | 默认值 |
@ApiImplicitParam注解的dataType、paramType两个属性的区别?
比如:
@ApiImplicitParam(name = "id",value = "用户id",required = true,dataType = "int",paramType = "body")
dataType=“int” 代表请求参数类型为int类型,当然也可以是Map、User、String等;
paramType=“body” 代表参数应该放在请求的什么地方:
header–>放在请求头。请求参数的获取:@RequestHeader(代码中接收注解)
query–>用于get请求的参数拼接。请求参数的获取:@RequestParam(代码中接收注解)
path(用于restful接口)–>请求参数的获取:@PathVariable(代码中接收注解)
body–>放在请求体。请求参数的获取:@RequestBody(代码中接收注解)
form(不常用)
@ApiResponses 和 @ApiResponse 的使用
@ApiResponses 主要封装方法的返回信息和 @ApiResponse 配置起来使用,@ApiResponse 定义返回的具体信息包括返回码、返回信息等。
使用示例:
@ApiOperation(value = "修改消息", notes = "根据参数修改消息")
@PutMapping(value = "message")
@ApiResponses({@ApiResponse(code = 100, message = "请求参数有误"),@ApiResponse(code = 101, message = "未授权"),@ApiResponse(code = 103, message = "禁止访问"),@ApiResponse(code = 104, message = "请求路径不存在"),@ApiResponse(code = 200, message = "服务器内部错误")
})
public Message modify(Message message) {
}
属性名称 | 备注 |
---|---|
code | http 的状态码 |
message | 描述 |
response | 默认响应类 Void |
reference | 参考 |
responseHeaders | 封装返回信息 |
responseContainer | 字符串 |
@ApiModel 和 @ApiModelProperty 的使用
在实际的项目中我们常常会封装一个对象作为返回值,@ApiModel 就是负责描述对象的信息,@ApiModelProperty 负责描述对象中属性的相关内容。
使用示例:
@ApiModel(description = "响应对象")
public class BaseResult<T> {private static final int SUCCESS_CODE = 0;private static final String SUCCESS_MESSAGE = "成功";@ApiModelProperty(value = "响应码", name = "code", required = true, example = "" + SUCCESS_CODE)private int code;@ApiModelProperty(value = "响应消息", name = "msg", required = true, example = SUCCESS_MESSAGE)private String msg;@ApiModelProperty(value = "响应数据", name = "data")private T data;
}
属性配置如下表所示:
属性名称 | 备注 |
---|---|
value | 属性描述 |
name | 如果配置覆盖属性名称 |
allowableValues | 允许的值 |
access | 可以不配置 |
notes | 没有使用 |
dataType | 数据类型 |
required | 是否为必传参数 |
position | 显示的顺序位置 |
hidden | 是否因此 |
example | 举例 |
readOnly | 只读 |
reference | 引用 |
3.快速上手
我们用一个例子来演示一下,使用SpringBoot整合Swagger2,实现SwaggerAPI文档测试。
这里我准备了一张商品表,对商品表中的数据进行CRUD,并使用swagger测试文档对接口进行测试
CREATE TABLE `tb_sku` (`id` varchar(20) NOT NULL COMMENT '商品id',`sn` varchar(100) NOT NULL COMMENT '商品条码',`name` varchar(200) NOT NULL COMMENT 'SKU名称',`price` int(20) NOT NULL COMMENT '价格(分)',`num` int(10) NOT NULL COMMENT '库存数量',`alert_num` int(11) DEFAULT NULL COMMENT '库存预警数量',`image` varchar(200) DEFAULT NULL COMMENT '商品图片',`images` varchar(2000) DEFAULT NULL COMMENT '商品图片列表',`weight` int(11) DEFAULT NULL COMMENT '重量(克)',`create_time` datetime DEFAULT NULL COMMENT '创建时间',`update_time` datetime DEFAULT NULL COMMENT '更新时间',`spu_id` varchar(20) DEFAULT NULL COMMENT 'SPUID',`category_id` int(10) DEFAULT NULL COMMENT '类目ID',`category_name` varchar(200) DEFAULT NULL COMMENT '类目名称',`brand_name` varchar(100) DEFAULT NULL COMMENT '品牌名称',`spec` varchar(200) DEFAULT NULL COMMENT '规格',`sale_num` int(11) DEFAULT '0' COMMENT '销量',`comment_num` int(11) DEFAULT '0' COMMENT '评论数',`status` char(1) DEFAULT '1' COMMENT '商品状态 1-正常,2-下架,3-删除',PRIMARY KEY (`id`),KEY `cid` (`category_id`),KEY `status` (`status`),KEY `updated` (`update_time`) ) ENGINE=InnoDB DEFAULT CHARSET=utf8 COMMENT='商品表';INSERT INTO tb_sku (id, sn, name, price, num, alert_num, image, images, weight, create_time, update_time, spu_id, category_id, category_name, brand_name, spec, sale_num, comment_num, status) VALUES('100000003145', '', 'vivo X23 8GB+128GB 幻夜蓝 水滴屏全面屏 游戏手机 移动联通电信全网通4G手机', 95900, 10000, 100, 'https://m.360buyimg.com/mobilecms/s720x720_jfs/t1/4612/28/6223/298257/5ba22d66Ef665222f/d97ed0b25cbe8c6e.jpg!q70.jpg.webp', 'https://m.360buyimg.com/mobilecms/s720x720_jfs/t1/4612/28/6223/298257/5ba22d66Ef665222f/d97ed0b25cbe8c6e.jpg!q70.jpg.webp', 10, '2019-05-01 00:00:00.0', '2019-05-01 00:00:00.0', '889527500', 0, '手机', 'vivo', '{''颜色'': ''红色'', ''版本'': ''8GB+128GB''}', 0, 0, '1'); INSERT INTO tb_sku (id, sn, name, price, num, alert_num, image, images, weight, create_time, update_time, spu_id, category_id, category_name, brand_name, spec, sale_num, comment_num, status) VALUES('100000004580', '', '薇妮(viney)女士单肩包 时尚牛皮女包百搭斜挎包女士手提大包(经典黑)', 87900, 10000, 100, 'https://m.360buyimg.com/mobilecms/s720x720_jfs/t5590/64/5811657380/234462/5398e856/5965e173N34179777.jpg!q70.jpg.webp', 'https://m.360buyimg.com/mobilecms/s720x720_jfs/t5590/64/5811657380/234462/5398e856/5965e173N34179777.jpg!q70.jpg.webp', 10, '2019-05-01 00:00:00.0', '2019-05-01 00:00:00.0', '451277100', 0, '真皮包', 'viney', '{''颜色'': ''黑色''}', 0, 0, '1'); INSERT INTO tb_sku (id, sn, name, price, num, alert_num, image, images, weight, create_time, update_time, spu_id, category_id, category_name, brand_name, spec, sale_num, comment_num, status) VALUES('100000006163', '', '巴布豆(BOBDOG)柔薄悦动婴儿拉拉裤XXL码80片(15kg以上)', 67100, 9999, 100, 'https://m.360buyimg.com/mobilecms/s720x720_jfs/t23998/350/2363990466/222391/a6e9581d/5b7cba5bN0c18fb4f.jpg!q70.jpg.webp', 'https://m.360buyimg.com/mobilecms/s720x720_jfs/t23998/350/2363990466/222391/a6e9581d/5b7cba5bN0c18fb4f.jpg!q70.jpg.webp', 10, '2019-05-01 00:00:00.0', '2019-05-01 00:00:00.0', '10000000616300', 1124, '拉拉裤', '巴布豆', '{}', 1, 0, '1'); INSERT INTO tb_sku (id, sn, name, price, num, alert_num, image, images, weight, create_time, update_time, spu_id, category_id, category_name, brand_name, spec, sale_num, comment_num, status) VALUES('100000011113', '', '莎米特SUMMIT拉杆箱22英寸PC材质万向轮旅行箱行李箱PC154T4A可扩容 法拉利红', 78900, 10000, 100, 'https://m.360buyimg.com/mobilecms/s720x720_jfs/t1/25363/12/2929/274060/5c21df3aE1789bda7/030af31afd116ae0.jpg!q70.jpg.webp', 'https://m.360buyimg.com/mobilecms/s720x720_jfs/t1/25363/12/2929/274060/5c21df3aE1789bda7/030af31afd116ae0.jpg!q70.jpg.webp', 10, '2019-05-01 00:00:00.0', '2019-05-01 00:00:00.0', '595502400', 0, '拉杆箱', '莎米特', '{''颜色'': ''红色''}', 0, 0, '1'); INSERT INTO tb_sku (id, sn, name, price, num, alert_num, image, images, weight, create_time, update_time, spu_id, category_id, category_name, brand_name, spec, sale_num, comment_num, status) VALUES('100000011127', '', '莎米特SUMMIT拉杆箱22英寸PC材质万向轮旅行箱行李箱PC154T4A可扩容 米白', 26600, 10000, 100, 'https://m.360buyimg.com/mobilecms/s720x720_jfs/t1/25363/12/2929/274060/5c21df3aE1789bda7/030af31afd116ae0.jpg!q70.jpg.webp', 'https://m.360buyimg.com/mobilecms/s720x720_jfs/t1/25363/12/2929/274060/5c21df3aE1789bda7/030af31afd116ae0.jpg!q70.jpg.webp', 10, '2019-05-01 00:00:00.0', '2019-05-01 00:00:00.0', '595502400', 0, '拉杆箱', '莎米特', '{''颜色'': ''米色''}', 0, 0, '1'); INSERT INTO tb_sku (id, sn, name, price, num, alert_num, image, images, weight, create_time, update_time, spu_id, category_id, category_name, brand_name, spec, sale_num, comment_num, status) VALUES('100000015158', '', '华为 HUAWEI 麦芒7 6G+64G 魅海蓝 全网通 前置智慧双摄 移动联通电信4G手机 双卡双待', 40800, 9998, 100, 'https://m.360buyimg.com/mobilecms/s720x720_jfs/t22642/312/2563982615/103706/1398b13d/5b865bb3N0409f0d0.jpg!q70.jpg.webp', 'https://m.360buyimg.com/mobilecms/s720x720_jfs/t22642/312/2563982615/103706/1398b13d/5b865bb3N0409f0d0.jpg!q70.jpg.webp', 10, '2019-05-01 00:00:00.0', '2019-05-01 00:00:00.0', '10000001516600', 106, '手机', '华为', '{''颜色'': ''蓝色''}', 2, 0, '1'); INSERT INTO tb_sku (id, sn, name, price, num, alert_num, image, images, weight, create_time, update_time, spu_id, category_id, category_name, brand_name, spec, sale_num, comment_num, status) VALUES('100000015166', '', '华为 HUAWEI 麦芒7 6G+64G 亮黑色 全网通 前置智慧双摄 移动联通电信4G手机 双卡双待', 89200, 10000, 100, 'https://m.360buyimg.com/mobilecms/s720x720_jfs/t22642/312/2563982615/103706/1398b13d/5b865bb3N0409f0d0.jpg!q70.jpg.webp', 'https://m.360buyimg.com/mobilecms/s720x720_jfs/t22642/312/2563982615/103706/1398b13d/5b865bb3N0409f0d0.jpg!q70.jpg.webp', 10, '2019-05-01 00:00:00.0', '2019-05-01 00:00:00.0', '10000001516600', 106, '手机', '华为', '{''颜色'': ''黑色''}', 0, 0, '1'); INSERT INTO tb_sku (id, sn, name, price, num, alert_num, image, images, weight, create_time, update_time, spu_id, category_id, category_name, brand_name, spec, sale_num, comment_num, status) VALUES('100000022652', '', 'vivo Y81s 刘海全面屏 3GB+32GB 香槟金 移动联通电信4G手机', 11700, 10000, 100, 'https://m.360buyimg.com/mobilecms/s720x720_jfs/t20707/78/2349564629/130172/50a245d8/5b8e00e2Nf0bcd624.jpg!q70.jpg.webp', 'https://m.360buyimg.com/mobilecms/s720x720_jfs/t20707/78/2349564629/130172/50a245d8/5b8e00e2Nf0bcd624.jpg!q70.jpg.webp', 10, '2019-05-01 00:00:00.0', '2019-05-01 00:00:00.0', '10000015453200', 0, '手机', 'vivo', '{''颜色'': ''槟色''}', 0, 0, '1');
项目结构
1.添加依赖包
<dependency><groupId>io.springfox</groupId><artifactId>springfox-swagger2</artifactId><version>2.8.0</version>
</dependency>
<dependency><groupId>io.springfox</groupId><artifactId>springfox-swagger-ui</artifactId><version>2.8.0</version>
</dependency>
2.编写Swagger配置类
com.jn.config.SwaggerConfig.java
package com.jn.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.spi.DocumentationType;
import springfox.documentation.spring.web.plugins.Docket;
import springfox.documentation.swagger2.annotations.EnableSwagger2;/*** @Author ScholarTang* @Date 2020/2/5 5:39 PM* @Desc swagger配置类*/@Configuration
@EnableSwagger2
public class SwaggerConfig {@Beanpublic Docket api() {return new Docket(DocumentationType.SWAGGER_2).apiInfo(apiInfo()).select()// 自行修改为自己的包路径.apis(RequestHandlerSelectors.basePackage("com.jn.controller")).paths(PathSelectors.any()).build();}public ApiInfo apiInfo() {return new ApiInfoBuilder()//swagger文档标题.title("swaggerAIP测试")//描述.description("测试 API 1.0 操作文档")//版本号.version("1.0").build();}
}
3.使用idea提供的工具生成domain & mapper & service
4.业务层代码
**com.jn.controller.SkuController.java**
package com.jn.controller;import com.jn.domain.Sku;
import com.jn.service.SkuService;
import com.jn.vo.Result;
import com.jn.vo.ResultUtils;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiImplicitParam;
import io.swagger.annotations.ApiOperation;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;import java.util.List;/*** @Author ScholarTang* @Date 2020/2/5 9:46 PM* @Desc 处理商品相关的业务*/@Slf4j
@RestController
@RequestMapping("/sku")
@Api(value = "商品管理",description = "商品管理",position = 100,protocols = "http")
public class SkuController {@Autowiredprivate SkuService service;@ApiOperation(value = "查询所有商品记录",notes = "查询所有商品记录",produces="application/json, application/xml",consumes="application/json, application/xml",response = List.class)@GetMapping("/findAllSku")public Result<List<Sku>> findAllSku() {Result<List<Sku>> result;try {List<Sku> skuList = service.list();result = ResultUtils.success(skuList);} catch (Exception e) {e.printStackTrace();result = ResultUtils.fail();}return result;}@ApiOperation(value = "添加商品",notes = "添加商品",produces="application/json, application/xml",consumes="application/json, application/xml")@ApiImplicitParam(value = "商品数据",name = "sku",dataType = "Sku",paramType = "body")@PostMapping("/addSku")public Result addSku (@RequestBody Sku sku) {Result result;boolean insert = sku.insert();if (insert) {result = ResultUtils.success(insert);} else {result = ResultUtils.fail();}return result;}@ApiOperation(value = "修改商品",notes = "修改商品",produces="application/json, application/xml",consumes="application/json, application/xml")@ApiImplicitParam(value = "商品数据",name = "sku",dataType = "Sku",paramType = "body")@PutMapping("/updateSku")public Result updateSku (@RequestBody Sku sku) {Result result = new Result();boolean updateById = sku.updateById();if (updateById) {result = ResultUtils.success(updateById);} else {result = ResultUtils.fail();}return result;}@ApiOperation(value = "删除商品",notes = "删除商品",produces="application/json, application/xml",consumes="application/json, application/xml")@ApiImplicitParam(value = "商品ID",name = "id",dataType = "int",paramType = "query")@DeleteMapping("/deleteSkuById")public Result deleteSkuById(@RequestParam(value = "id") Integer id) {Result result;boolean removeById = service.removeById(id);if (removeById) {result = ResultUtils.success(removeById);} else {result = ResultUtils.fail();}return result;}
}
5.运行项目访问localhost:8080/swagger-ui.html (这个端口号是你项目的端口)
6.使用Try it out进行测试
使用 Swagger 创建的在线 API 还有一个非常强大的功能,可以在页面直接测试接口的可用性,这样在前端和后端接口调试出现问题时,可以非常方便地利用此功能进行接口验证。在上面参数讲解过程中,我们发现每个接口描述右侧都有一个按钮 try it out,单击 try it out 按钮即可进入表单页面,如下:
码云地址
https://gitee.com/Tang1314521/swagger-blog.git