From 77a174035a49025d8cf6318a35eb88ccff17c6be Mon Sep 17 00:00:00 2001
From: LGH <1242479791@qq.com>
Date: Thu, 16 Apr 2020 10:20:16 +0800
Subject: [PATCH] =?UTF-8?q?=E6=B7=BB=E5=8A=A0swagger=E6=96=87=E6=A1=A3?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
---
doc/Swagger文档.md | 208 +++++++++++++++++++++++++++++++++++++++++++
1 file changed, 208 insertions(+)
create mode 100644 doc/Swagger文档.md
diff --git a/doc/Swagger文档.md b/doc/Swagger文档.md
new file mode 100644
index 0000000..d48513c
--- /dev/null
+++ b/doc/Swagger文档.md
@@ -0,0 +1,208 @@
+> 有很多人不清楚我们的swagger ui的路径,由于我们使用了更为好用的`swagger-bootstrap-ui`,实际上使 域名+端口 +/doc.html,如:http://localhost:8086/doc.html
+
+
+
+在没有Swagger之前,我们需要自己手写文档,手写文档的出现问题:
+
+1. 文档更新时需要要与前端人员进行对接,文档存在更新不及时
+2. 接口文档多,没有进行分组管理,增加管理难度
+3. 不能直接在线接口调试,通常需要借助工具(如postman),效率大大降低
+4. 接口说明与返回结果不明确
+
+而通过swagger就能轻松解决这些问题,而且`spirngboot`整合swagger也相对简单
+
+[swagger官网](https://swagger.io/)
+
+## 添加依赖
+
+```
+
+ io.springfox
+ springfox-swagger2
+ 1.9.3
+
+
+ com.github.xiaoymin
+ swagger-bootstrap-ui
+ 2.9.2
+
+```
+
+## 添加配置类并开启
+
+在**yami-shop-api**工程中的**config**文件下,有swagger相应的配置类,只要了解具体能配置哪些东西就好了,毕竟这个东西配置一次之后就不用再动了
+
+```java
+@Configuration
+@EnableSwagger2
+public class SwaggerConfiguration {
+
+ @Bean
+ public Docket baseRestApi() {
+ return new Docket(DocumentationType.SWAGGER_2)
+ .apiInfo(apiInfo())
+ .groupName("基础版")
+ .select()
+ .apis(RequestHandlerSelectors.basePackage("com.yami.shop.api"))
+ .paths(PathSelectors.any())
+ .build();
+ }
+ @Bean
+ public ApiInfo apiInfo() {
+ return new ApiInfoBuilder()
+ .title("亚米商城接口文档")
+ .description("亚米商城接口文档Swagger版")
+ .termsOfServiceUrl("http://www.gz-yami.com/")
+ .contact(new Contact("广州亚米信息科技有限公司","https://www.gz-yami.com/", ""))
+ .version("1.0")
+ .build();
+ }
+}
+```
+
+特别要注意的是里面配置了api文件也就是controller包的路径,不然生成的文档扫描不到接口
+
+```java
+apis(RequestHandlerSelectors.basePackage("com.yami.shop.api"))
+```
+
+用`@Configuration`注解该类,让spring托管这个类,`@Bean`标注方法等价于XML中配置bean
+
+用`@EnableSwagger2`标识要开启`Swagger2`
+
+## 接口使用
+
+在配置好之后,我们就可以对swagger进行使用,比如在`AreaController`类中
+
+```java
+@RestController
+@RequestMapping("/p/area")
+@Api(tags="省市区接口")
+public class AreaController {
+
+ @Autowired
+ private AreaService areaService;
+
+ @GetMapping("/listByPid")
+ @ApiOperation(value="获取省市区信息", notes="根据省市区的pid获取地址信息")
+ @ApiImplicitParam(name = "pid", value = "省市区的pid(pid为0获取所有省份)", required = true, dataType = "String")
+ public ResponseEntity> listByPid(Long pid){
+ List list = areaService.listByPid(pid);
+ return ResponseEntity.ok(list);
+ }
+}
+```
+
+`@Api(tags="省市区接口")`定义标签分组接口,在这个类下定义的所有接口将位于这个标签之下
+
+`@ApiOperation()`定义具体的接口标题信息,notes可以为这个标签添加注释
+
+`@ApiImplicitParam()`对应的参数列表信息,用户告诉前端开发人员,这个接口需要传递什么参数及参数的说明
+
+如有多个参数需要说明,可使用`@ApiImplicitParams()`下面可包含多个`@ApiImplicitParam()`
+
+## 实体类
+
+```java
+@Data
+@TableName("tz_area")
+public class Area implements Serializable {
+ private static final long serialVersionUID = -6013320537436191451L;
+ @TableId
+ @ApiModelProperty(value = "地区id",required=true)
+ private Long areaId;
+
+ @ApiModelProperty(value = "地区名称",required=true)
+ private String areaName;
+
+ @ApiModelProperty(value = "地区上级id",required=true)
+ private Long parentId;
+
+ @ApiModelProperty(value = "地区层级",required=true)
+ private Integer level;
+
+ @TableField(exist=false)
+ private List areas;
+}
+```
+
+`@ApiModelProperty()`利用这个注解可以告诉前端开发人员该字段代表的含义
+
+## 常用注解
+
+| 注解 | 作用 |
+| ------------------ | ------------------------------------ |
+| @Api | 修饰整个类,描述Controller的作用 |
+| @ApiOperation | 描述一个类的一个方法,或者说一个接口 |
+| @ApiParam | 单个参数描述 |
+| @ApiModel | 用对象来接收参数 |
+| @ApiProperty | 用对象接收参数时,描述对象的一个字段 |
+| @ApiResponse | HTTP响应其中1个描述 |
+| @ApiResponses | HTTP响应整体描述 |
+| @ApiIgnore | 使用该注解忽略这个API |
+| @ApiError | 发生错误返回的信息 |
+| @ApiImplicitParam | 一个请求参数 |
+| @ApiImplicitParams | 多个请求参数 |
+
+
+
+## 分页参数的文档以及关于swagger文档的骚操作
+
+
+
+我们仔细留意swagger文档,可以发现 swagger文档返回接口数据的url为:`/v2/api-docs` 。这个url被 `springfox.documentation.swagger2.web.Swagger2Controlle#getDocumentation()` 关联。通过`jsonSerializer.toJson(swagger)` 生成特定的json文档。
+
+
+
+当我们使用`PageParam` 这个分页参数生成文档的时候,总是会返回泛型里面的对象信息,我们根据无论使用`@ApiParam(hidden = true)` 又或者是 `@JsonIgnore` 都无效,所以我们可以修改自己的`jsonSerializer`生成的响应的json
+
+
+
+自定义Swagger 的序列化,去除分页参数中的records值
+
+```java
+public class SpringfoxJsonSerializer extends JsonSerializer {
+
+ public SpringfoxJsonSerializer(List modules) {
+ super(modules);
+ }
+
+ @Override
+ public Json toJson(Object toSerialize) {
+ if (!(toSerialize instanceof Swagger)) {
+ return super.toJson(toSerialize);
+ }
+ Swagger swagger = (Swagger)toSerialize;
+
+ swagger.getPaths().forEach((key, path) ->{
+ Operation get = path.getGet();
+ if (get != null) {
+
+ List parameters = get.getParameters();
+ if (parameters != null) {
+ parameters.removeIf(parameter -> parameter.getName().startsWith("records[0]."));
+ }
+ }
+ });
+
+ return super.toJson(swagger);
+ }
+}
+```
+
+
+
+新序列化的bean
+
+```java
+@Configuration
+public class SpringFoxJsonSerializerConfig {
+
+ @Bean
+ @Primary
+ public JsonSerializer yamiSpringfoxJsonSerializer(List moduleRegistrars) {
+ return new SpringfoxJsonSerializer(moduleRegistrars);
+ }
+}
+```
+