swagger官网 对 swagger 的描述如下:
Swagger takes the manual work out of API documentation, with a range of solutions for generating, visualizing, and maintaining API docs.
Simplify API development for users, teams, and enterprises with the Swagger open source and professional toolset.
Swagger提供了用于生成,可视化和维护API文档的一系列解决方案,从而使API文档不再需要人工操作。
借助Swagger开源和专业工具集,为用户,团队和企业简化API开发。
我的总结:Swagger 是一套基于 OpenAPI 规范构建的开源工具,可以帮助我们设计、构建、使用和测试 Rest API。
现在大部分公司都采用前后端分离开发的模式,前端和后端工程师各司其职。这就要求有一份及时更新且完整的Rest API 文档来提高工作效率。Swagger 解决的问题主要有以下三点:
这里通过构建一个简单的Spring Boot项目,并使用Swagger注解,来演示如何使用Swagger
这里没有添加springfox-swagger2和springfox-swagger2-ui依赖,而是使用knife4j-spring-boot-starter依赖,官网地址:https://doc.xiaominfo.com/knife4j/
<dependency>
<groupId>javax.validationgroupId>
<artifactId>validation-apiartifactId>
<version>2.0.1.Finalversion>
dependency>
<dependency>
<groupId>com.github.xiaoymingroupId>
<artifactId>knife4j-spring-boot-starterartifactId>
<version>2.0.3version>
dependency>
<dependency>
<groupId>org.projectlombokgroupId>
<artifactId>lombokartifactId>
dependency>
<dependency>
<groupId>org.springframework.bootgroupId>
<artifactId>spring-boot-starter-webartifactId>
dependency>
注意:RequestHandlerSelectors.basePackage("com.jourwon.springboot.knife4j.controller")
为 Controller 包路径,不然生成的文档扫描不到接口,也可以使用RequestHandlerSelectors.any()
配置
/**
* Swagger2配置类
*
* @author JourWon
* @date 2020/6/1
*/
@EnableKnife4j
@EnableSwagger2
@Configuration
@Import(value = {BeanValidatorPluginsConfiguration.class})
public class Swagger2Config {
@Bean
public Docket createRestApi() {
return new Docket(DocumentationType.SWAGGER_2)
.apiInfo(apiInfo())
.select()
.apis(RequestHandlerSelectors.any())
.paths(PathSelectors.any())
.build();
}
private ApiInfo apiInfo() {
return new ApiInfoBuilder()
// 标题
.title("我的Swagger API文档")
// 描述
.description("使用Knife4j构建API文档")
// 作者信息
.contact(new Contact("ThinkWon", "https://thinkwon.blog.csdn.net/", "[email protected]"))
// 服务网址
.termsOfServiceUrl("https://thinkwon.blog.csdn.net/")
// 版本
.version("1.0.0")
.build();
}
}
/**
* 用户
*
* @author JourWon
* @date 2020/6/1
*/
@Data
@NoArgsConstructor
@AllArgsConstructor
@ApiModel(value = "用户", description = "查询用户")
public class UserDTO implements Serializable {
private static final long serialVersionUID = 78806598597025327L;
@ApiModelProperty(value = "用户id")
private Integer userId;
@ApiModelProperty(value = "用户名")
private String username;
}
/**
* 用户controller
*
* @author JourWon
* @date 2020/6/1
*/
@RestController
@RequestMapping(value = {"/user"})
@Api(tags = {"用户controller"})
public class UserController {
private List<UserDTO> list = new ArrayList<>();
@PostConstruct
private void post() {
list.add(new UserDTO(1, "JourWon"));
list.add(new UserDTO(2, "Jobs"));
list.add(new UserDTO(3, "JackMa"));
}
@GetMapping("/list")
@ApiOperation(value = "查询用户列表")
public List<UserDTO> list() {
return list;
}
@GetMapping("/page")
@ApiOperation(value = "分页查询用户列表")
@ApiImplicitParams({
@ApiImplicitParam(name = "pageNum", value = "当前页数"),
@ApiImplicitParam(name = "pageSize", value = "每页记录数")
})
public List<UserDTO> page(
@RequestParam(defaultValue = "1", required = false) Integer pageNum, @RequestParam(defaultValue = "10", required = false) Integer pageSize) {
return list;
}
@GetMapping("/{userId}")
@ApiOperation(value = "根据用户id查询用户")
public UserDTO get(@PathVariable("userId") Integer userId) {
for (UserDTO userDTO : list) {
if (userDTO.getUserId().equals(userId)) {
return userDTO;
}
}
return new UserDTO();
}
@PostMapping
@ApiOperation(value = "新增用户")
public Boolean insert(@RequestBody @ApiParam(name = "UserDTO", value = "新增用户参数") UserDTO userDTO) {
list.add(userDTO);
return true;
}
@DeleteMapping("/{userId}")
@ApiOperation(value = "根据用户id删除用户")
public Boolean delete(@PathVariable("userId") Integer userId) {
Iterator<UserDTO> iterator = list.iterator();
while (iterator.hasNext()) {
if (iterator.next().getUserId().equals(userId)) {
iterator.remove();
return true;
}
}
return false;
}
@PutMapping
@ApiOperation(value = "更新用户信息")
@ApiResponses({
@ApiResponse(code = 400, message = "请求参数没填好"),
@ApiResponse(code = 404, message = "请求路径没有或页面跳转路径不对")
})
public Boolean update(@RequestBody @ApiParam(name = "UserDTO", value = "更新用户参数") UserDTO userDTO) {
Iterator<UserDTO> iterator = list.iterator();
while (iterator.hasNext()) {
UserDTO next = iterator.next();
if (next.getUserId().equals(userDTO.getUserId())) {
next.setUsername(userDTO.getUsername());
return true;
}
}
return false;
}
}
这个controller有了六个接口,分别是:
启动一下项目,然后在浏览器中访问 http://localhost:8080/doc.html
主页展示API文档基本信息,包括简介,作者,版本等信息
同时可以看到用户controller的所有接口
这里我们调试以下查询用户列表的接口
至此,Spring Boot集成Swagger2,构建API文档已经完成
用在请求的类上,表示对类的说明
注解属性 | 类型 | 描述 |
---|---|---|
tags | String[] | 描述请求类的作用,非空时会覆盖value的值 |
value | String | 描述请求类的作用 |
非常用参数 | ||
produces | String | 设置 MIME 类型列表(output),例:“application/json, application/xml”,默认为空 |
consumes | String | 设置 MIME 类型列表(input),例:“application/json, application/xml”,默认为空 |
protocols | String | 设置特定协议,例:http, https, ws, wss |
authorizations | Authorization[] | 获取授权列表(安全声明),如果未设置,则返回一个空的授权值 |
hidden | boolean | 默认为 false,配置为 true 将在文档中隐藏 |
description | String | 对 api 资源的描述,在 1.5 版本后不再支持 |
basePath | String | 基本路径可以不配置,在 1.5 版本后不再支持 |
position | int | 如果配置多个 Api 想改变显示的顺序位置,在 1.5 版本后不再支持 |
示例
@Api(tags = {"用户controller"})
public class UserController {}
用在请求类的方法上,说明方法的用途和作用
注解属性 | 类型 | 描述 |
---|---|---|
value | String | 方法的简要说明 |
notes | String | 方法的备注说明 |
非常用参数 | ||
tags | String[] | 操作标签,非空时将覆盖value的值 |
response | Class> | 响应类型(即返回对象) |
responseContainer | String | 声明包装的响应容器(返回对象类型)。有效值为 “List”, “Set” or “Map” |
responseReference | String | 指定对响应类型的引用。将覆盖任何指定的response()类 |
httpMethod | String | 指定HTTP方法,“GET”, “HEAD”, “POST”, “PUT”, “DELETE”, “OPTIONS” and “PATCH” |
position | int | 如果配置多个 Api 想改变显示的顺序位置,在 1.5 版本后不再支持 |
nickname | String | 第三方工具唯一标识,默认为空 |
responseHeaders | ResponseHeader[] | 响应头列表 |
code | int | 响应的HTTP状态代码。默认 200 |
extensions | Extension[] | 扩展属性列表数组 |
produces | String | 设置 MIME 类型列表(output),例:“application/json, application/xml”,默认为空 |
consumes | String | 设置 MIME 类型列表(input),例:“application/json, application/xml”,默认为空 |
protocols | String | 设置特定协议,例:http, https, ws, wss |
authorizations | Authorization[] | 获取授权列表(安全声明),如果未设置,则返回一个空的授权值 |
hidden | boolean | 默认为 false,配置为 true 将在文档中隐藏 |
示例
@GetMapping("/list")
@ApiOperation(value = "查询用户列表")
public List<UserDTO> list() {
return list;
}
可用在方法,参数和字段上,一般用在请求体参数上,描述请求体信息
注解属性 | 类型 | 描述 |
---|---|---|
name | String | 参数名称,参数名称可以覆盖方法参数名称,路径参数必须与方法参数一致 |
value | String | 参数的简要说明 |
required | boolean | 参数是否必须传,默认为 false (路径参数必填) |
defaultValue | String | 参数的默认值 |
非常用参数 | ||
allowableValues | String | 限制参数的可接受值。1.以逗号分隔的列表 2.范围值 3.设置最小值/最大值 |
access | String | 允许从API文档中过滤参数 |
allowMultiple | boolean | 指定参数是否可以通过具有多个事件接受多个值,默认为 false |
example | String | 单个示例 |
examples | Example | 参数示例。仅适用于 BodyParameters |
hidden | boolean | 默认为 false,配置为 true 将在文档中隐藏 |
@PostMapping
@ApiOperation(value = "新增用户")
public Boolean insert(@RequestBody @ApiParam(name = "UserDTO", value = "新增用户参数") UserDTO userDTO) {
list.add(userDTO);
return true;
}
用在请求的方法上,表示一组参数说明,里面是@ApiImplicitParam
列表
用在 @ApiImplicitParams
注解中,一个请求参数的说明
注解属性 | 类型 | 描述 |
---|---|---|
name | String | 参数名称,参数名称可以覆盖方法参数名称,路径参数必须与方法参数一致 |
value | String | 参数的说明、解释 |
required | boolean | 参数是否必须传,默认为 false (路径参数必填) |
paramType | String | 参数的位置,header 请求参数的获取:@RequestHeader ;query 请求参数的获取:@RequestParam ;path(用于 restful 接口)–> 请求参数的获取:@PathVariable ;body(不常用);form(不常用) |
dataType | String | 参数类型,默认 String,其它值 dataType=“Integer” |
defaultValue | String | 参数的默认值 |
非常用参数 | ||
allowableValues | String | 限制参数的可接受值。1.以逗号分隔的列表 2.范围值 3.设置最小值/最大值 |
access | String | 允许从API文档中过滤参数 |
allowMultiple | boolean | 指定参数是否可以通过具有多个事件接受多个值,默认为 false |
example | String | 单个示例 |
examples | Example | 参数示例。仅适用于 BodyParameters |
@GetMapping("/page")
@ApiOperation(value = "分页查询问题列表")
@ApiImplicitParams({
@ApiImplicitParam(name = "pageNum", value = "当前页数"),
@ApiImplicitParam(name = "pageSize", value = "每页记录数")
})
public List<UserDTO> page(
@RequestParam(defaultValue = "1", required = false) Integer pageNum, @RequestParam(defaultValue = "10", required = false) Integer pageSize) {
return list;
}
用在请求的方法上,表示一组响应
用在 @ApiResponses
中,一般用于表达一个错误的响应信息
注解属性 | 类型 | 描述 |
---|---|---|
code | int | 响应状态码 |
message | String | 信息,例如 “请求参数没填好” |
response | Class> | 抛出异常的类 |
示例
@PutMapping
@ApiOperation(value = "更新用户信息")
@ApiResponses({
@ApiResponse(code = 400, message = "请求参数没填好"),
@ApiResponse(code = 404, message = "请求路径没有或页面跳转路径不对")
})
public Boolean update(@RequestBody @ApiParam(name = "UserDTO", value = "更新用户参数") UserDTO userDTO) {}
用在实体类(模型)上,表示相关实体的描述。
注解属性 | 类型 | 描述 |
---|---|---|
value | String | 模型的备用名称 |
description | String | 该类的详细说明 |
示例
@ApiModel(value = "用户", description = "查询用户")
public class UserDTO implements Serializable
用在实体类属性上,表示属性的相关描述。
注解属性 | 类型 | 描述 |
---|---|---|
value | String | 属性简要描述 |
name | String | 重写属性名称 |
dataType | Stirng | 重写属性类型 |
required | boolean | 参数是否必传,默认为 false |
example | Stirng | 属性示例 |
非常用参数 | ||
hidden | boolean | 是否在文档中隐藏该属性,默认false |
allowEmptyValue | boolean | 是否允许为空,默认false |
allowableValues | String | 限制参数的可接受值。1.以逗号分隔的列表 2.范围值 3.设置最小值/最大值 |
readOnly | boolean | 将属性设定为只读,默认false |
reference | String | 指定对相应类型定义的引用,覆盖指定的任何参数值 |
示例
@ApiModelProperty(value = "用户id")
private Integer userId;
@ApiModelProperty(value = "用户名")
private String username;