Swagger2简介

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。

使用Swagger解决的问题

现在大部分公司都采用前后端分离开发的模式,前端和后端工程师各司其职。这就要求有一份及时更新且完整的Rest API 文档来提高工作效率。Swagger 解决的问题主要有以下三点:

  1. 保证文档的时效性:只需要少量的注解,Swagger 就可以根据代码自动生成 API 文档,代码变文档跟着变
  2. 接口请求参数和返回结果不明确的问题
  3. 在线测试接口

Spring Boot集成Swagger2

这里通过构建一个简单的Spring Boot项目,并使用Swagger注解,来演示如何使用Swagger

添加依赖

这里没有添加springfox-swagger2和springfox-swagger2-ui依赖,而是使用knife4j-spring-boot-starter依赖,官网地址:https://doc.xiaominfo.com/knife4j/

<!-- 一些校验的依赖,不然启动会报NoClassDefFoundError: javax/validation/constraints/Min -->
<dependency>
    <groupId>javax.validation</groupId>
    <artifactId>validation-api</artifactId>
    <version>2.0.1.Final</version>
</dependency>

<!-- Spring Boot单服务架构使用最新版的knife4j依赖,已经继承swagger依赖,同时增强UI实现 -->
<dependency>
    <groupId>com.github.xiaoymin</groupId>
    <artifactId>knife4j-spring-boot-starter</artifactId>
    <version>2.0.3</version>
</dependency>

<!-- lombok依赖 -->
<dependency>
    <groupId>org.projectlombok</groupId>
    <artifactId>lombok</artifactId>
</dependency>

<!-- spring-boot-starter-web依赖 -->
<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-web</artifactId>
</dependency>

添加Swagger2Config配置类

注意: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/", "thinkwon@163.com"))
                // 服务网址
                .termsOfServiceUrl("https://thinkwon.blog.csdn.net/")
                // 版本
                .version("1.0.0")
                .build();
    }

}

编写接口

用户DTO
/**
 * 用户
 *
 * @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

/**
 * 用户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有了六个接口,分别是:

  1. /user/list,get请求方式:查询用户列表
  2. /user/page,get请求方式:分页查询用户列表
  3. /user/{userId},get请求方式:根据用户id查询用户
  4. /user,post请求方式:新增用户
  5. /user,put请求方式:更新用户信息
  6. /user/{userId},delete请求方式:根据用户id删除用户

访问接口文档

启动一下项目,然后在浏览器中访问 http://localhost:8080/doc.html

主页展示API文档基本信息,包括简介,作者,版本等信息

在这里插入图片描述

同时可以看到用户controller的所有接口

在这里插入图片描述

这里我们调试以下查询用户列表的接口

在这里插入图片描述

至此,Spring Boot集成Swagger2,构建API文档已经完成

Swagger2常用注解说明

Controller相关注解

@Api

用在请求的类上,表示对类的说明

注解属性类型描述
tagsString[]描述请求类的作用,非空时会覆盖value的值
valueString描述请求类的作用
非常用参数
producesString设置 MIME 类型列表(output),例:“application/json, application/xml”,默认为空
consumesString设置 MIME 类型列表(input),例:“application/json, application/xml”,默认为空
protocolsString设置特定协议,例:http, https, ws, wss
authorizationsAuthorization[]获取授权列表(安全声明),如果未设置,则返回一个空的授权值
hiddenboolean默认为 false,配置为 true 将在文档中隐藏
descriptionString对 api 资源的描述,在 1.5 版本后不再支持
basePathString基本路径可以不配置,在 1.5 版本后不再支持
positionint如果配置多个 Api 想改变显示的顺序位置,在 1.5 版本后不再支持

示例

@Api(tags = {"用户controller"})
public class UserController {}

接口相关注解

@ApiOperation

用在请求类的方法上,说明方法的用途和作用

注解属性类型描述
valueString方法的简要说明
notesString方法的备注说明
非常用参数
tagsString[]操作标签,非空时将覆盖value的值
responseClass<?>响应类型(即返回对象)
responseContainerString声明包装的响应容器(返回对象类型)。有效值为 “List”, “Set” or “Map”
responseReferenceString指定对响应类型的引用。将覆盖任何指定的response()类
httpMethodString指定HTTP方法,“GET”, “HEAD”, “POST”, “PUT”, “DELETE”, “OPTIONS” and “PATCH”
positionint如果配置多个 Api 想改变显示的顺序位置,在 1.5 版本后不再支持
nicknameString第三方工具唯一标识,默认为空
responseHeadersResponseHeader[]响应头列表
codeint响应的HTTP状态代码。默认 200
extensionsExtension[]扩展属性列表数组
producesString设置 MIME 类型列表(output),例:“application/json, application/xml”,默认为空
consumesString设置 MIME 类型列表(input),例:“application/json, application/xml”,默认为空
protocolsString设置特定协议,例:http, https, ws, wss
authorizationsAuthorization[]获取授权列表(安全声明),如果未设置,则返回一个空的授权值
hiddenboolean默认为 false,配置为 true 将在文档中隐藏

示例

@GetMapping("/list")
@ApiOperation(value = "查询用户列表")
public List<UserDTO> list() {
    return list;
}
@ApiParam

可用在方法,参数和字段上,一般用在请求体参数上,描述请求体信息

注解属性类型描述
nameString参数名称,参数名称可以覆盖方法参数名称,路径参数必须与方法参数一致
valueString参数的简要说明
requiredboolean参数是否必须传,默认为 false (路径参数必填)
defaultValueString参数的默认值
非常用参数
allowableValuesString限制参数的可接受值。1.以逗号分隔的列表 2.范围值 3.设置最小值/最大值
accessString允许从API文档中过滤参数
allowMultipleboolean指定参数是否可以通过具有多个事件接受多个值,默认为 false
exampleString单个示例
examplesExample参数示例。仅适用于 BodyParameters
hiddenboolean默认为 false,配置为 true 将在文档中隐藏
@PostMapping
@ApiOperation(value = "新增用户")
public Boolean insert(@RequestBody @ApiParam(name = "UserDTO", value = "新增用户参数") UserDTO userDTO) {
    list.add(userDTO);
    return true;
}
@ApiImplicitParams

用在请求的方法上,表示一组参数说明,里面是@ApiImplicitParam列表

@ApiImplicitParam

用在 @ApiImplicitParams 注解中,一个请求参数的说明

注解属性类型描述
nameString参数名称,参数名称可以覆盖方法参数名称,路径参数必须与方法参数一致
valueString参数的说明、解释
requiredboolean参数是否必须传,默认为 false (路径参数必填)
paramTypeString参数的位置,header 请求参数的获取:@RequestHeader;query 请求参数的获取:@RequestParam;path(用于 restful 接口)–> 请求参数的获取:@PathVariable;body(不常用);form(不常用)
dataTypeString参数类型,默认 String,其它值 dataType=“Integer”
defaultValueString参数的默认值
非常用参数
allowableValuesString限制参数的可接受值。1.以逗号分隔的列表 2.范围值 3.设置最小值/最大值
accessString允许从API文档中过滤参数
allowMultipleboolean指定参数是否可以通过具有多个事件接受多个值,默认为 false
exampleString单个示例
examplesExample参数示例。仅适用于 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

用在请求的方法上,表示一组响应

@ApiResponse

用在 @ApiResponses 中,一般用于表达一个错误的响应信息

注解属性类型描述
codeint响应状态码
messageString信息,例如 “请求参数没填好”
responseClass<?>抛出异常的类

示例

@PutMapping
@ApiOperation(value = "更新用户信息")
@ApiResponses({
    @ApiResponse(code = 400, message = "请求参数没填好"),
    @ApiResponse(code = 404, message = "请求路径没有或页面跳转路径不对")
})
public Boolean update(@RequestBody @ApiParam(name = "UserDTO", value = "更新用户参数") UserDTO userDTO) {}

Model相关注解

@ApiModel

用在实体类(模型)上,表示相关实体的描述。

注解属性类型描述
valueString模型的备用名称
descriptionString该类的详细说明

示例

@ApiModel(value = "用户", description = "查询用户")
public class UserDTO implements Serializable
@ApiModelProperty

用在实体类属性上,表示属性的相关描述。

注解属性类型描述
valueString属性简要描述
nameString重写属性名称
dataTypeStirng重写属性类型
requiredboolean参数是否必传,默认为 false
exampleStirng属性示例
非常用参数
hiddenboolean是否在文档中隐藏该属性,默认false
allowEmptyValueboolean是否允许为空,默认false
allowableValuesString限制参数的可接受值。1.以逗号分隔的列表 2.范围值 3.设置最小值/最大值
readOnlyboolean将属性设定为只读,默认false
referenceString指定对相应类型定义的引用,覆盖指定的任何参数值

示例

@ApiModelProperty(value = "用户id")
private Integer userId;

@ApiModelProperty(value = "用户名")
private String username;
Logo

权威|前沿|技术|干货|国内首个API全生命周期开发者社区

更多推荐