在目前前后端分离的模式中无论是前端开发还是后端开发基本上都被文档折磨过,前端开发经常会遇到后端接口改变,调整等文档未及时更新问题,而后端开发又会在文档的编写与维护上耗费大量的精力。
平时手写文档出现的问题:
- 文档需要更新的时候,需要再次发送一份给前端,也就是文档更新交流不及时。
- 接口返回结果不明确
- 不能直接在线测试接口,通常需要使用工具,比如:
Postman
- 接口文档太多,不好管理
市场既然有需求,那么肯定就会有方案。解决方案多了就行成了标准,这就是Swagger的由来。
根据官网的介绍,Swagger是一系列用于Restful API开发的工具,开源的部分包括:
OpenAPI Specification
:API规范,规定了如何描述一个系统的API
Swagger Codegen
:用于通过API规范生成服务端和客户端代码
Swagger Editor
:用来编写API规范
Swagger UI
:用于展示API规范
我们目前在开发使用的主要是Springfox Swagger,Springfox 是一个通过扫描代码提取代码中的信息,生成API文档的工具。在Swagger的教程中的都会提到的@Api
,@ApiModel
,@ApiOperation
等这些注解并不是Springfox的,而是Swagger的,Spring-swagger2这个包依赖了swagger-core,而这些注解是swagger-core里面的。但是swagger-core这个包只支持JAX-RS2,而不支持我们常用的Spring MVC,而Springfox 就是把这些适用于JAX-RS2中的注解适配到Spring MVC上。所以springfox 又可以称之为swagger2,swagger的二代
一丶Swagger2配置
1. 引入maven依赖
在pom.xml文件中加入
<!-- https://mvnrepository.com/artifact/io.springfox/springfox-swagger2 -->
<dependency>
<groupId>io.springfox</groupId>
<artifactId>springfox-swagger2</artifactId>
<version>2.9.2</version>
</dependency>
<!-- https://mvnrepository.com/artifact/io.springfox/springfox-swagger-ui -->
<dependency>
<groupId>io.springfox</groupId>
<artifactId>springfox-swagger-ui</artifactId>
<version>2.9.2</version>
</dependency>
<dependency>
<groupId>com.github.xiaoymin</groupId>
<artifactId>swagger-bootstrap-ui</artifactId>
<version>1.9.6</version>
</dependency>
添加了一个bootstrap框架的ui,更直观访问地址是http://localhost:端口号/doc.html
2. 配置Swagger2
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;
@Configuration
public class Swagger2Configuration {
@Bean
public Docket createRestApi() {
return new Docket(DocumentationType.SWAGGER_2)
.apiInfo(apiInfo())
.select()
.apis(RequestHandlerSelectors.basePackage("com.app.dome.service"))//扫描服务的包
.paths(PathSelectors.any())
.build();
}
private ApiInfo apiInfo() {
return new ApiInfoBuilder()
.title("API 文档")
.description("")
.termsOfServiceUrl("")
.version("1.0.0")
.build();
}
}
3. 开启Swagger2
Application 中加上注解 @EnableSwagger2
表示开启 Swagger
二丶使用Swagger2
Swagger常用注解
请求类中使用的注解
1. @Api,用在请求的类上,表示对类的说明
(1)tags=“说明该类的作用,可以在UI界面上看到的注解”
(2)value=“该参数没什么意义,在UI界面上也看不到,所以不需要配置”
@Api(tags = "当前controller的说明")
@Controlle
@RequestMapper("/stock")
public class StockController {
}
2. @ApiOperation:用在请求的方法上,说明方法的用途、作用
(1)value=“说明方法的用途、作用”
(2) notes=“方法的备注说明”
@ApiOperation("当前方法的说明")
@RequestMapping(value = "/api/stock", method = RequestMethod.POST)
@ApiResponses({@ApiResponse(code = 200, message = "查询成功", response = StockSelectVo.class)})
public Object stock(@RequestBody StockSelectBo stockSelectBo) {
return null;
}
3. @ApiImplicitParams:用在请求的方法上,表示一组参数说明
@ApiImplicitParam:用在**@ApiImplicitParams**注解中,指定一个请求参数的各个方面
(1) name:参数名
(2)value:参数的汉字说明、解释
(3)required:参数是否必须传
(4)paramType:参数放在哪个地方
· header --> 请求参数的获取:@RequestHeader
· query --> 请求参数的获取:@RequestParam
· path(用于restful接口)–> 请求参数的获取:@PathVariable
· body(不常用)
· form(不常用)
(5)dataType:参数类型,默认String,其它值dataType=“Integer”
(6)defaultValue:参数的默认值
@ApiOperation("查询测试")
@GetMapping("select")
@ApiImplicitParams({
@ApiImplicitParam(name="name",value="用户名",dataType="string", paramType = "query"),
@ApiImplicitParam(name="id",value="用户id",dataType="long", paramType = "query")})
public void select(@RequestParam String id,@RequestParam long id){
}
对于@ApiImplicitParam的paramType:query、form域中的值需要使用@RequestParam获取,
header域中的值需要使用@RequestHeader来获取,
path域中的值需要使用@PathVariable来获取,
body域中的值使用@RequestBody来获取,否则可能出错;
而且如果paramType是body,name就不能是body,否则有问题。
4.@ApiParam:用在方法的参数中
(1)name : 参数名字
(2)value:参数说明
(3)required:是否为非必传 true必传 false非必传
(4)type:参数类型
@ApiOperation("查询测试")
@GetMapping("select")
public void select(@ApiParam(name="id",value="数据id") String id){
}
@ApiParam的功能和@ApiImplicitParam是相同的,但是@ApiImplicitParam的用法更广,在一些非JAX-RS的场合比如使用servlet提供HTTP接口),只能使用@ApiImplicitParam进行参数说明,这是因为接口并不展示入参的名称,所以没有地方去使用@ApiParam,只能在@ApiImplicitParam中去写入
5. @ApiResponses:用在请求的方法上,表示一组响应
@ApiResponse:用在**@ApiResponses**中,一般用于表达一个错误的响应信息
(1)code:数字,例如400
(2)message:信息,例如"请求参数没填好"
(3)response:抛出异常的类
@ApiOperation("查询测试")
@GetMapping("select")
@ApiResponses({@ApiResponse(code = 200, message = "查询成功", response = StockSelectVo.class)})
public void select(@RequestParam String id,@RequestParam long id){
}
用于响应类上的注解
1. @ApiModel:用于响应类上,表示一个返回响应数据的信息
@ApiModel(description= "返回响应数据")
public class RestMessage implements Serializable{
}
2. @ApiModelProperty 用在属性上,描述响应类的属性
@ApiModel(description= "返回响应数据")
public class RestMessage implements Serializable{
@ApiModelProperty(value = "是否成功")
private boolean success=true;
@ApiModelProperty(value = "返回对象")
private Object data;
@ApiModelProperty(value = "错误编号")
private Integer errCode;
@ApiModelProperty(value = "错误信息")
private String message;
}