第19章 基于Springboot使用Swagger2构建强大的API文档

1,269 阅读4分钟

在上一篇文章【Spring Boot新手指南:一文学会RESTful API开发】中,我们深入探讨了如何使用Spring MVC构建RESTful API,并且了解了多种注解的应用,如@RestController、@RequestMapping、@GetMapping等,它们共同帮助我们设计出了既简洁又高效的API接口。然而,在实际开发过程中,除了关注API的功能实现外,维护一份清晰、准确的API文档同样至关重要。这不仅能提升团队内部的协作效率,还能极大地便利外部用户的接入与使用。鉴于此,接下来我们将介绍如何基于Spring Boot使用Swagger2来构建强大的API文档。Swagger2不仅能够自动生成文档,还提供了便捷的测试功能,使得API的设计与维护变得更加直观与高效。让我们一起进入Swagger2的世界,看看它是如何简化这一过程的。

任务描述

任务要求

使用IDEA开发工具构建一个项目多模块工程。study-springboot-chapter17学习关于Springboot开发前端控制层,方便实现前后端分离

  1. 基于study-springboot工程,复制study-springboot-chapter18标准项目,坐标groupId(com.cbitedu)、artifactId(study-springboot-chapter18),其他默认
  2. 继承study-springboot工程依赖
  3. 构建Restful API,引入Swagger2文档

任务收获

  1. Spring Boot开发Restful API服务
  2. 学会使用JUnit完成单元测试
  3. 掌握web开发原理
  4. 熟悉SpringMVC的基础配置
  5. 熟悉Swagger2生成标准服务接口文档

任务准备

环境要求

  1. JDK1.8+
  2. MySQL8.0.27+
  3. Maven 3.6.1+
  4. IDEA/VSCode

工程目录要求

study-springboot-chapter18

任务实施

整合Swagger2

下面,我们以上面仓库中的RESTFUL API工程进行整合改造。

第一步:添加swagger-spring-boot-starter依赖

在pom.xml中加入依赖,具体如下:

        <!-- 引入 Swagger 依赖 -->
        <dependency>
            <groupId>io.springfox</groupId>
            <artifactId>springfox-swagger2</artifactId>
            <version>2.9.2</version>
        </dependency>
        <!-- 引入 Swagger UI 依赖,以实现 API 接口的 UI 界面 -->
        <dependency>
            <groupId>io.springfox</groupId>
            <artifactId>springfox-swagger-ui</artifactId>
            <version>2.9.2</version>
        </dependency>

如果想使用swagger-ui加强版,则引入如下依赖

Knife4j是一个集Swagger2 和 OpenAPI3为一体的增强解决方案

doc.xiaominfo.com/

<!--引入Knife4j的官方start包,Swagger2基于Springfox2.10.5项目-->
<dependency>
    <groupId>com.github.xiaoymin</groupId>
    <!--使用Swagger2-->
    <artifactId>knife4j-spring-boot-starter</artifactId>
    <version>2.0.9</version>
</dependency>

第二步:配置项Swagger2、WebMvcConfigurerConfig

package com.cbitedu.springboot.config;

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.service.Contact;
import springfox.documentation.spi.DocumentationType;
import springfox.documentation.spring.web.plugins.Docket;
import springfox.documentation.swagger2.annotations.EnableSwagger2;

@EnableSwagger2// 标记项目启用 Swagger API 接口文档
@Configuration
public class Swagger2 {

    @Bean
    public Docket createRestApi() {
        // 创建 Docket 对象
        return new Docket(DocumentationType.SWAGGER_2)// 文档类型,使用 Swagger2
                .apiInfo(apiInfo())
                .select()
                // 扫描 Controller 包路径,获得 API 接口
                .apis(RequestHandlerSelectors.basePackage("com.cbitedu.springboot.controller"))
                .paths(PathSelectors.any())
                // 构建出 Docket 对象
                .build();
    }
    /**
     * 创建 API 信息
     */

    private ApiInfo apiInfo() {
        return new ApiInfoBuilder()
                .title("微服务管理平台")
                .description("描述")
                .termsOfServiceUrl("服务条款")
                .version("1.0.0")
                .contact(new Contact("creatorblue", "http://www.creatorblue.com", "zhujianwu@creatorblue.com"))
                .build();
    }
}

WebMvcConfigurerConfig

package com.cbitedu.springboot.config;

import org.springframework.context.annotation.Configuration;
import org.springframework.web.servlet.config.annotation.EnableWebMvc;
import org.springframework.web.servlet.config.annotation.ResourceHandlerRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;

@Configuration
@EnableWebMvc
public class WebMvcConfigurerConfig implements WebMvcConfigurer {

    @Override
    public void addResourceHandlers(ResourceHandlerRegistry registry) {
        registry.addResourceHandler("swagger-ui.html")
                .addResourceLocations("classpath:/META-INF/resources/");
        registry.addResourceHandler("/webjars/**")
                .addResourceLocations("classpath:/META-INF/resources/webjars/");
    }
}

第三步:实体测试类

package com.cbitedu.springboot.entity;

import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;

@ApiModel("用户 VO")
public class UserVO {

    @ApiModelProperty(value = "用户编号", required = true, example = "1024")
    private Integer id;
    @ApiModelProperty(value = "账号", required = true, example = "yudaoyuanma")
    private String username;

    public Integer getId() {
        return id;
    }

    public UserVO setId(Integer id) {
        this.id = id;
        return this;
    }

    public String getUsername() {
        return username;
    }

    public UserVO setUsername(String username) {
        this.username = username;
        return this;
    }

}

 

第四步:编写用户控制类

package com.cbitedu.springboot.controller;

import com.cbitedu.springboot.entity.UserVO;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiImplicitParam;
import io.swagger.annotations.ApiImplicitParams;
import io.swagger.annotations.ApiOperation;
import org.springframework.web.bind.annotation.*;

import java.util.ArrayList;
import java.util.List;
import java.util.UUID;

@RestController
@RequestMapping("/users")
@Api(tags = "用户管理API接口")
public class UserController {

    @GetMapping("/list")
    @ApiOperation(value = "查询用户列表", notes = "目前仅仅是作为测试,所以返回用户全列表")
    public List<UserVO> list() {
        // 查询列表
        List<UserVO> result = new ArrayList<>();
        result.add(new UserVO().setId(1).setUsername("zhangsan"));
        result.add(new UserVO().setId(2).setUsername("lisi"));
        result.add(new UserVO().setId(3).setUsername("wangwu"));
        // 返回列表
        return result;
    }

    @GetMapping("/get")
    @ApiOperation("获得指定用户编号的用户")
    @ApiImplicitParam(name = "id", value = "用户编号", paramType = "query", dataTypeClass = Integer.class, required = true, example = "1024")
    public UserVO get(@RequestParam("id") Integer id) {
        // 查询并返回用户
        return new UserVO().setId(id).setUsername(UUID.randomUUID().toString());
    }

    @ApiOperation(value = "创建用户", notes = "根据User对象创建用户")
    @ApiImplicitParam(name = "user", value = "用户详细实体user", required = true, dataType = "User")
    @PostMapping("/add")
    public void add() {
        System.out.println("创建用户");
    }


    @ApiOperation(value = "更新用户详细信息", notes = "根据url的id来指定更新对象,并根据传过来的user信息来更新用户详细信息")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "id", value = "用户ID", required = true, dataType = "Long"),
            @ApiImplicitParam(name = "user", value = "用户详细实体user", required = true, dataType = "User")
    })
    @RequestMapping(value = "/update/{id}", method = RequestMethod.PUT)
    public void update(@PathVariable Integer id) {
        System.out.println("更新用户详细信息");
    }

    @PostMapping("/delete")
    @ApiOperation(value = "删除指定用户编号的用户")
    @ApiImplicitParam(name = "id", value = "用户编号", paramType = "query", dataTypeClass = Integer.class, required = true, example = "1024")
    public Boolean delete(@RequestParam("id") Integer id) {
        // 删除用户记录
        Boolean success = false;
        // 返回是否更新成功
        return success;
    }
}

第五步:启动应用,访问:http://localhost:81/swagger-ui.html,就可以看到如下的接口文档页面:

加强版的访问地址:http://localhost:81/doc.html

注意:如果工程中引入了shiro等过滤器,则需要放行方能访问,否则访问不到主页面,弹出错误页面

// swagger配置
filterMap.put("/swagger-ui/**", "anon");
filterMap.put("/v2/**", "anon");
filterMap.put("/webjars/**", "anon");
filterMap.put("/swagger-resources/**", "anon");

实验实训

1、实现Swagger2文档分组排序功能

2、完成与SpringFox整合