一、背景
相信无论是前端还是后端开发,都或多或少地被接口文档折磨过。前端经常抱怨后端给的接口文档与实际情况不一致。后端又觉得编写及维护接口文档会耗费不少精力,经常来不及更新。其实无论是前端调用后端,还是后端调用后端,都期望有一个好的接口文档。但是这个接口文档对于程序员来说,就跟注释一样,经常会抱怨别人写的代码没有写注释,然而自己写起代码起来,最讨厌的,也是写注释。所以仅仅只通过强制来规范大家是不够的,随着时间推移,版本迭代,接口文档往往很容易就跟不上代码了。[1]
二、Swagger是什么
Swagger是一套规范,只要按这个规范定义接口,就可以使用Swagger衍生出来的一系列工具,就可以做到生成各种格式的接口文档,生成多种语言的客户端和服务端的代码,以及在线接口调试等等。
但即使如此,维护这个yml或json格式的描述文件本身也是有一定负担的。尤其是当后面持续迭代开发的时候,经常会忘记更新这个描述文件,直接修改代码。久而久之,这个描述文件也就失去了参考意义。
之后Spring将Swagger规范纳入自身标准,成为了Springfox。通过在项目中引入Springfox,可以扫描相关的代码,生成该描述文件,进而生成与代码一致的接口文档和客户端代码。这种通过代码生成接口文档的形式,在后面需求持续迭代的项目中,显得尤为重要和高效。
三、 Swagger框架
Swagger Codegen: 通过Codegen 可以将描述文件生成html格式和cwiki形式的接口文档,同时也能生成多钟语言的服务端和客户端的代码。支持通过jar包,docker,node等方式在本地化执行生成。也可以在后面的Swagger Editor中在线生成。
Swagger UI:提供了一个可视化的UI页面展示描述文件。接口的调用方、测试、项目经理等都可以在该页面中对相关接口进行查阅和做一些简单的接口请求。该项目支持在线导入描述文件和本地部署UI项目。
Swagger Editor: 类似于markendown编辑器的编辑Swagger描述文件的编辑器,该编辑支持实时预览描述文件的更新效果。也提供了在线编辑器和本地部署编辑器两种方式。
Swagger Inspector: 感觉和postman差不多,是一个可以对接口进行测试的在线版的postman。比在Swagger UI里面做接口请求,会返回更多的信息,也会保存你请求的实际请求参数等数据。
Swagger Hub:集成了上面所有项目的各个功能,你可以以项目和版本为单位,将你的描述文件上传到Swagger Hub中。在Swagger Hub中可以完成上面项目的所有工作,需要注册账号,分免费版和收费版。
PS:
Springfox Swagger: Spring 基于swagger规范,可以将基于SpringMVC和Spring Boot项目的项目代码,自动生成JSON格式的描述文件。本身不是属于Swagger官网提供的,在这里列出来做个说明,方便后面作一个使用的展开。
四、Swagger-Editor使用
4.1 Swagger-Editor工具包
请自行寻找资源
4.2 使用方法
(1)解压zip,找到\swagger-editor_tools\swagger-editor_tools\tools\swagger文件夹,解压swagger-editor-master.zip
(2)打开index.html即可进行编辑,左侧编辑,右侧可实时展示。
五、Spring Boot项目中使用Swagger
这里是用的是Swagger2
5.1 maven依赖
<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>
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-databind</artifactId>
<version>2.9.5</version>
</dependency>
(PS:Swagger和Spring Boot 2存在兼容问题,需要添加jackson-databind包)
5.2 在Application中启用@EnableSwagger2注解
5.3 创建Swagger2配置类
package com.example.config;
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 org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
/**
* swagger配置类
*
* @author w00453985
* @since 2019-12-12
*/@Configuration
public class Swagger2Set {@
Value("${swagger.enable}")
private boolean enableSwagger;
/**
* swagger配置
*
* @return swagger对象
*/@Bean
public Docket createRestApi() {
return new Docket(DocumentationType.SWAGGER_2)
.apiInfo(apiInfo())
.enable(enableSwagger)
.select()
.apis(RequestHandlerSelectors.basePackage("com.example.controller"))
.paths(PathSelectors.any())
.build();
}
private ApiInfo apiInfo() {
return new ApiInfoBuilder()
.title("Demo-学生管理系统")
.description("学生管理系统,用于测试swagger使用,测试接口文档自动化生成,作者wuzhiyong w00453985")
.termsOfServiceUrl("http://3ms.huawei.com/Ufield/w00453985#blogs")
.version("1.0")
.build();
}
}
5.4 Controller中添加更详细的接口说明
swagger相关注解用途如下:
package com.example.controller;
import com.example.model.QueryStudentScoreReq;
import com.example.model.StudentDto;
import com.example.model.StudentScoreDto;
import com.example.service.StudentMgmtService;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiImplicitParam;
import io.swagger.annotations.ApiOperation;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.bind.annotation.RestController;
/**
* controller层
*
* @author w00453985
* @since 2019-2-11
*/
@Api(value = "用户controller", tags = {"学生管理接口"})
@RequestMapping(path = "/")
@RestController
public class MyController {
private static final String RET_OK = "OK";
private StudentMgmtService service;
/**
* 默认构造器
*
* @param service 注入服务
*/
@Autowired
public MyController(StudentMgmtService service) {
this.service = service;
}
/**
* 心跳检查
*
* @return 状态OK
*/
@GetMapping("/heartbeat")
@ResponseBody
@ApiOperation(value = "心跳检查", notes = "心跳检查,可用于SLB健康检查")
public String heartBeat() {
return RET_OK;
}
/**
* 查询学生信息
*
* @param id 学生id
* @return 学生信息
*/
@GetMapping("/student/queryinfo")
@ResponseBody
@ApiImplicitParam(name = "id", value = "学生id", required = true, dataType = "String")
public StudentDto queryStudentInfo(String id) {
return new StudentDto("02011409", "jiangping");
}
/**
* 查询分数
*
* @param req 查询分数请求
* @return 分数响应
*/
@PostMapping("/student/queryscore")
@ResponseBody
@ApiOperation(value = "查询分数", notes = "查询学生某门科目的分数")
public StudentScoreDto queryStudentScore(@RequestBody QueryStudentScoreReq req) {
return new StudentScoreDto("02011409", "Physical Education", 100);
}
}
5.5 配置文件中配置服务器端口号和swagger配置
## swagger
swagger.enable=true
server.port=8081
5.6 添加swagger-ui.html接口页面文件
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Swagger UI</title>
<link rel="icon" type="image/png" href="webjars/springfox-swagger-ui/images/favicon-32x32.png" sizes="32x32"/>
<link rel="icon" type="image/png" href="webjars/springfox-swagger-ui/images/favicon-16x16.png" sizes="16x16"/>
<link href='webjars/springfox-swagger-ui/css/typography.css' media='screen' rel='stylesheet' type='text/css'/>
<link href='webjars/springfox-swagger-ui/css/reset.css' media='screen' rel='stylesheet' type='text/css'/>
<link href='webjars/springfox-swagger-ui/css/screen.css' media='screen' rel='stylesheet' type='text/css'/>
<link href='webjars/springfox-swagger-ui/css/reset.css' media='print' rel='stylesheet' type='text/css'/>
<link href='webjars/springfox-swagger-ui/css/print.css' media='print' rel='stylesheet' type='text/css'/>
<script src='webjars/springfox-swagger-ui/lib/object-assign-pollyfill.js' type='text/javascript'></script>
<script src='webjars/springfox-swagger-ui/lib/jquery-1.8.0.min.js' type='text/javascript'></script>
<script src='webjars/springfox-swagger-ui/lib/jquery.slideto.min.js' type='text/javascript'></script>
<script src='webjars/springfox-swagger-ui/lib/jquery.wiggle.min.js' type='text/javascript'></script>
<script src='webjars/springfox-swagger-ui/lib/jquery.ba-bbq.min.js' type='text/javascript'></script>
<script src='webjars/springfox-swagger-ui/lib/handlebars-4.0.5.js' type='text/javascript'></script>
<script src='webjars/springfox-swagger-ui/lib/lodash.min.js' type='text/javascript'></script>
<script src='webjars/springfox-swagger-ui/lib/backbone-min.js' type='text/javascript'></script>
<script src='webjars/springfox-swagger-ui/swagger-ui.min.js' type='text/javascript'></script>
<script src='webjars/springfox-swagger-ui/lib/highlight.9.1.0.pack.js' type='text/javascript'></script>
<script src='webjars/springfox-swagger-ui/lib/highlight.9.1.0.pack_extended.js' type='text/javascript'></script>
<script src='webjars/springfox-swagger-ui/lib/jsoneditor.min.js' type='text/javascript'></script>
<script src='webjars/springfox-swagger-ui/lib/marked.js' type='text/javascript'></script>
<script src='webjars/springfox-swagger-ui/lib/swagger-oauth.js' type='text/javascript'></script>
<script src='webjars/springfox-swagger-ui/springfox.js' type='text/javascript'></script>
<!--国际化操作:选择中文版 -->
<script src='webjars/springfox-swagger-ui/lang/translator.js' type='text/javascript'></script>
<script src='webjars/springfox-swagger-ui/lang/zh-cn.js' type='text/javascript'></script>
</head>
<body class="swagger-section">
<div id='header'>
<div class="swagger-ui-wrap">
<a id="logo" href="http://swagger.io">![](webjars/springfox-swagger-ui/images/logo_small.png)<span
class="logo__title">swagger</span></a>
<form id='api_selector'>
<div class='input'>
<select id="select_baseUrl" name="select_baseUrl"></select>
</div>
<div class='input'><input placeholder="http://example.com/api" id="input_baseUrl" name="baseUrl"
type="text"/></div>
<div id='auth_container'></div>
<div class='input'><a id="explore" class="header__btn" href="#" data-sw-translate>Explore</a></div>
</form>
</div>
</div>
<div id="message-bar" class="swagger-ui-wrap" data-sw-translate></div>
<div id="swagger-ui-container" class="swagger-ui-wrap"></div>
</body>
</html>
5.7 启动服务,访问http://localhost:8081/swagger-ui.html
显示如下:
点击http://localhost:8081/v2/api-docs可查看json格式的接口文档,可导入到swagger-editor中进行查看。
参考资料:
Swagger介绍及使用
https://www.jianshu.com/p/349e130e40d5
https://blog.csdn.net/sanyaoxu_2/article/details/80555328