6.3 使用 Swagger 生成 Web API 文档

news2025/1/13 10:25:52

第6章 构建 RESTful 服务

6.1 RESTful 简介
6.2 构建 RESTful 应用接口
6.3 使用 Swagger 生成 Web API 文档
6.4 实战:实现 Web API 版本控制

6.3 使用 Swagger 生成 Web API 文档

高质量的 API 文档在系统开发的过程中非常重要。本节介绍什么是 Swagger, 如何在 Spring Boot 项目中集成 Swagger 构建 RESTful API 文档,以及为 Swagger 配置 Token 等通用参数。

6.3.1 什么是 Swagger

Swagger 是一个规范和完整的框架,用于生成、描述、调用和可视化 RESTful 风格的 Web 服务,是非常流行的 API 表达工具。

普通的API文档存在的问题:

  1. 由于接口众多,并且细节复杂(需要考虑不同的 HTTP 请求类型、HTTP 头部信息、HTTP 请求内容等),创建这样一份高质量的文档是一件非常繁琐的工作。
  2. 随着需求的不断变化,接口文档必须同步修改,就很容易出现文档和业务不一致的情况。

为了解决这些问题,Swagger 应运而生,它能够自动生成完善的 RESTful API 文档,并根据后台代码的修改同步更新。这样既可以减少维护接口文档的工作量,又能将说明内容集成到实现代码中,让维护文档和修改代码合为一体,实现代码逻辑与说明文档的同步更新。另外,Swagger 也提供了完整的测试页面来测试 API,让 API 测试变得轻松、简单。

6.3.2 使用 Swagger 生成 Web API 文档

1、配置 Swagger 的依赖。

在pom.xml 文件中引入 Swagger 相关依赖包:springfox-swagger2springfox-swagger-ui。如下:

pom.xml

        <!--Swagger2 依赖配置-->
        <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.5.0</version>
        </dependency>

2、创建 Swagger2 配置类。

Swagger2Config.java

package com.example.restfulproject.comm.config;

import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.servlet.config.annotation.ResourceHandlerRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;
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 springfox.documentation.swagger2.annotations.EnableSwagger2;

/**
 * Swagger2 配置类
 */
@Configuration
@EnableSwagger2
public class Swagger2Config implements WebMvcConfigurer {
    @Bean
    public Docket createRestApi() {
        return new Docket(DocumentationType.SWAGGER_2)
                .apiInfo(apiInfo())
                .select()
                .apis(RequestHandlerSelectors.basePackage("com.example.restfulproject"))
                .paths(PathSelectors.any())
                .build();
    }

    private ApiInfo apiInfo() {
        return new ApiInfoBuilder()
                .title("Spring Boot 中使用 Swagger2 构建 RESTful APIs")
                .description("Spring Boot 相关文章请关注:https://blog.csdn.net/shipley_leo")
                .termsOfServiceUrl("https://blog.csdn.net/shipley_leo")
                .contact("shipley_leo")
                .version("1.0")
                .build();
    }

    @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/");
    }
}

在上面的示例中,我们在 SwaggerConfig 的类上添加了@Configuration@EnableSwagger2两个注解。

  • @Configuration 注解让 Spring Boot 来加载该类配置。
  • @EnableSwagger2 注解启用 Swagger2,通过配置一个 Docket Bean,来配置映射路径和要扫描的接口所在的位置。
  • apiInfo() 方法主要配置 Swagger2 文档网站的信息,比如网站的标题、网站的描述、使用的协议等。

3、添加文档说明内容。

SwaggerController.java

package com.example.restfulproject.controller;

import com.example.restfulproject.comm.utils.JSONResult;
import com.example.restfulproject.model.User;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiImplicitParam;
import io.swagger.annotations.ApiOperation;
import org.springframework.web.bind.annotation.*;

/**
 * 使用 Swagger 生成 Web API 文档
 */
@Api(tags = {"用户接口"})
@RestController
@RequestMapping(value = "/swagger")
public class SwaggerController {

    @ApiOperation(value = "创建用户", notes = "根据 User 对象创建用户")
    @PostMapping(value = "/user")
    public JSONResult save(@RequestBody User user) {
        System.out.println("用户创建成功:" + user.getName());
        return JSONResult.ok(201, "用户创建成功");
    }

    @ApiOperation(value = "更新用户详细信息", notes = "根据 id 来指定更新对象,并根据传过来的 user 信息来更新用户详细信息")
    @PutMapping(value = "/user")
    public JSONResult update(@RequestBody User user) {
        System.out.println("用户修改成功:" + user.getName());
        return JSONResult.ok(203, "用户修改成功");
    }

    @ApiOperation(value = "删除用户", notes = "根据 url 的 id 来指定删除对象")
    @ApiImplicitParam(name = "userId", value = "用户ID", required = true, dataType = "String", paramType = "path")
    @DeleteMapping(value = "/user/{userId}")
    public JSONResult delete(@PathVariable String userId) {
        System.out.println("用户删除成功:" + userId);
        return JSONResult.ok(204, "用户删除成功");
    }

    @ApiOperation(value = "查询用户", notes = "通过用户 ID 获取用户信息")
    @ApiImplicitParam(name = "userId", value = "用户ID", required = true, dataType = "String", paramType = "path")
    @GetMapping(value = "/user/{userId}")
    public JSONResult queryUserById(@PathVariable String userId) {
        User user = new User();
        user.setId(userId);
        user.setName("zhangsan");
        user.setAge(20);
        System.out.println("获取用户成功:" + userId);
        return JSONResult.ok(200, "获取用户成功", user);
    }

}

在上面的示例中,主要为 SwaggerController 中的接口增加了接口信息描述,包括接口的用途,请求参数说明等。

  • @Api 注解:用来给整个控制器(Controller)增加说明。
  • @ApiOperation 注解:用来给各个 API 方法增加说明。
  • @ApiImplicitParams、@ApiImplicitParam 注解:用来给参数增加说明。

4、查看生成的 API 文档。

(1)查看生成的 API 文档

完成上面的配置和代码修改之后,Swagger2 就集成到 Spring Boot 项目中了。接下来启动项目,在浏览器中访问 http://localhost:8080/swagger-ui.html, Swagger 会自动构建接口说明文档,如图所示。

swagger-ui.html(Swagger-UI 启动页面):
swagger-ui.html.png

用户接口:
用户接口.png

创建用户:
创建用户.png

更新用户详细信息:
更新用户详细信息.png

删除用户:
删除用户.png

查询用户:
查询用户.png

Swagger 自动将用户管理模块的全部接口信息展现出来,包括接口功能说明、调用方式、请求参数、返回数据结构等信息。

(2)Swagger 接口验证测试

在 Swagger 页面上,我们发现每个接口描述左下方都有一个按钮“Try it out!”,点击该按钮即可调用该接口进行测试。如图所示,输入userId请求参数“1001”,然后单击“Try it out!”按钮就会将请求发送到后台,从而进行接口验证测试。

调用接口进行测试:
调用接口进行测试.png

答疑解惑

报错问题:Spring Boot 整合 Swagger 用于生成 Web API 文档的过程中,出现了一个报错“Failed to start bean ‘documentationPluginsBootstrapper’; nested exception is java.lang.NullPointerException”。

原因分析:这个报错是因为 springboot 升级到 2.6.0之后,swagger版本和springboot出现了不兼容情况。

解决方案:有三种解决方案可供参考使用,分别为:

  • 方案一:在启动类 或 配置类 添加注解 @EnableWebMvc。
  • 方案二:在 application.properties 配置文件添加配置: properties spring.mvc.pathmatch.matching-strategy=ant_path_matcher
  • 方案三:降低Spring Boot 版本,比如可以考虑将Spring Boot版本降低为2.5.6。

更加详细的说明,可参考:Failed to start bean ‘documentationPluginsBootstrapper‘; nested exception is java.lang.NullPointerEx

6.3.3 为 Swagger 添加 token 参数

很多时候,客户端在调用 API 时需要在 HTTP 的请求头携带通用参数,比如权限验证的 token 参数等。但是 Swagger 是怎么描述此类参数的呢?接下来通过示例演示如何为 Swagger 添加固定的请求参数。

其实非常简单,修改 Swagger2Config 配置类,利用 ParameterBuilder 构成请求参数,具体示例代码如下:

package com.example.restfulproject.comm.config;

import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.servlet.config.annotation.ResourceHandlerRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;
import springfox.documentation.builders.ApiInfoBuilder;
import springfox.documentation.builders.ParameterBuilder;
import springfox.documentation.builders.PathSelectors;
import springfox.documentation.builders.RequestHandlerSelectors;
import springfox.documentation.schema.ModelRef;
import springfox.documentation.service.ApiInfo;
import springfox.documentation.service.Parameter;
import springfox.documentation.spi.DocumentationType;
import springfox.documentation.spring.web.plugins.Docket;
import springfox.documentation.swagger2.annotations.EnableSwagger2;

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

/**
 * Swagger2 配置类
 */
@Configuration
@EnableSwagger2
public class Swagger2Config implements WebMvcConfigurer {
    @Bean
    public Docket createRestApi() {
        List<Parameter> parameters = new ArrayList<Parameter>();
        ParameterBuilder parameterBuilder = new ParameterBuilder();
        parameterBuilder.name("token").description("token令牌")
                .modelRef(new ModelRef("string")).parameterType("header").required(false).build();
        parameters.add(parameterBuilder.build());

        return new Docket(DocumentationType.SWAGGER_2)
                .apiInfo(apiInfo())
                .select()
                .apis(RequestHandlerSelectors.basePackage("com.example.restfulproject.controller"))
                .paths(PathSelectors.any())
                .build()
                .globalOperationParameters(parameters);
    }

    ...
}

在上面的示例中,通过 ParameterBuilder 类把 token 作为全局统一的参数添加到 HTTP 的请求头中。系统所有的 API 都会统一加上此参数。

完成之后重新启动应用,再次查看接口,如图所示,我们可以看到接口参数中已经支持发送 token 请求参数。

添加token参数.png

6.3.4 Swagger 常用注解

Swagger 提供了一系列注解来描述接口信息,包括接口说明、请求方法、请求参数、返回信息等,常用注解如表所示。

Swagger常用注解说明

注解属性取值类型说明示例
@Apivalue字符串可用在class头上,class描述@Api(value="xxx", description="xxx")
description字符串
@ApiOperationvalue字符串可用在方法头上,参数的描述容器@ApiOperation(value="xxx",notes="xxx")
notes字符串
@ApiImplicitParamsvalue@ApiImplicitParam数组可用在方法头上,参数的描述容器@ApiImplicitParams({@ApiImplicitParam1,@ApiImplicitParam2,...})
@ApiImplicitParamname字符串,与参数命名对应可用在@ApiImplicitParams中@ApiImplicitParam(name = "userId", value = "用户ID", required = true, dataType = "String", paramType = "path")
value字符串参数中文描述
required布尔值true/false
dataType字符串参数类型
paramType字符串参数请求方式:query/path
defaultValue字符串在API测试中的默认值
@ApiResponsesvalue@ApiResponse数组可用在方法头上,参数的描述容器@ApiResponses({@ApiResponse1,@ApiResponse2,...})
@ApiResponsecode整数可用在@ApiResponses中@ApiResponse(code=200, message="Successful")
message字符串错误描述
@ApiIgnorevalue字符串忽略这个API
@ApiError发生错误的返回信息

在实际项目中,Swagger 除了提供 @ApiImplicitParams 注解描述简单的参数之外,还提供了用于对象参数的 @ApiModel 和 @ApiModelProperty 两个注解,用于封装的对象作为传入参数或返回数据。

  • @ApiModel 负责描述对象的信息
  • @ApiModelProperty 负责描述对象中属性的相关内容

以上是在项目中常用的一些注解,利用这些注解就可以构建出清晰的 API 文档。

来源:《Spring Boot 从入门到实战》学习笔记

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/356837.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

15-基础加强-2-xml(约束)枚举注解

文章目录1.xml1.1概述【理解】(不用看)1.2标签的规则【应用】1.3语法规则【应用】1.4xml解析【应用】1.5DTD约束【理解】1.5.1 引入DTD约束的三种方法1.5.2 DTD语法&#xff08;会阅读&#xff0c;然后根据约束来写&#xff09;1.6 schema约束【理解】1.6.1 编写schema约束1.6.…

基于高频方波电压信号注入的永磁同步电机无传感器控制仿真及其原理介绍

基于方波信号注入的永磁同步电机无传感器控制仿真及其原理介绍 注入的高频方波信号为&#xff1a; 可以得到估计轴的高频响应电流为: 当向定子绕组注入高频电压信号时,所注入的高频信号频率远高于基波信号频率。因此&#xff0c;IPMSM 在a-β轴的电压模型可以表示为: 假定…

二叉树OJ(一)二叉树的最大深度 二叉搜索树与双向链表 对称的二叉树

二叉树的最大深度 二叉树中和为某一值的路径(一) 二叉搜索树与双向链表 对称的二叉树 二叉树的最大深度 描述 求给定二叉树的最大深度&#xff0c; 深度是指树的根节点到任一叶子节点路径上节点的数量。 最大深度是所有叶子节点的深度的最大值。 &#xff08;注&#xff1a;…

Xcode Archives打包上传 / 导出ipa 发布至TestFlight

Xcode自带的Archives工具可以傻瓜式上传到App Store Connect分发这里以分发到TestFlight为例进行操作。 环境&#xff1a;Xcode 14 一&#xff1a;Archives打包 选择Xcode菜单栏的Product&#xff0c;Archives选项&#xff0c;需要等待编译完成&#xff0c;进入如下界面&…

【C语言】初识结构体

☃️内容专栏&#xff1a;【C语言】初阶部分 ☃️本文概括&#xff1a;继初识C语言&#xff0c;对C语言结构体初阶部分进行归纳与总结。 ☃️本文作者&#xff1a;花香碟自来_ ☃️发布时间&#xff1a;2023.2.19 一、结构体的声明 结构体&#xff08;类型&#xff09;是一些…

字符设备驱动基础(二)

目录 一、五种IO模型------读写外设数据的方式 二、阻塞与非阻塞 三、多路复用 3.1 应用层&#xff1a;三套接口select、poll、epoll 3.2 驱动层&#xff1a;实现poll函数 四、信号驱动 4.1 应用层&#xff1a;信号注册fcntl 4.2 驱动层&#xff1a;实现fasync函数 一、…

CSAPP学习笔记——虚拟内存(二)

案例研究 Intel Core i7 该处理底层的Haswell微体系结构允许64位的虚拟和物理地址空间&#xff0c;而现在的Core i7实现支持48位&#xff08;256TB&#xff09;虚拟地址空间和52位&#xff08;4PB&#xff09;物理地址空间&#xff0c;这对目前来说已经完全够用了。&#xff…

Liunx(狂神课堂笔记)

一.常用命令 1. cd 切换目录 cd ./* 当前目录cd /* 绝对路径cd .. 返回上一级目录cd ~ 回到当前目录pwd …

定点数的表示和运算

文章目录真值&#xff08;有正负号&#xff09;和机器数&#xff08;0正1负&#xff09;原码整数小数补码负数的补数正数的补数[y]~补~ > [-y]~补~反码小结移码移位运算加减法运算溢出判断真值&#xff08;有正负号&#xff09;和机器数&#xff08;0正1负&#xff09; 无符…

链表OJ(六)链表相加(一) 链表相加(二)

目录 链表相加(一) 链表相加(二) 描述 二与一相比多了俩次反转而已 链表相加(一) 描述 给定两个非空链表逆序存储的的非负整数&#xff0c;每个节点只存储一位数组。 请你把两个链表相加以下相同方法返回链表&#xff0c;保证两个数都不会以 0 开头。 【我的解法】长到…

实例五:MATLAB APP design-APP登录界面的设计

一、APP 界面设计展示 注:在账号和密码提示框输入相应的账号和密码后,点击登录按钮,即可跳转到程序中设计的工作界面。 二、APP设计界面运行结果展示

使用继承的虚函数表

​ 代码 #include <iostream> using namespace std;class Father { public:virtual void func1() { cout << "Father::func1" << endl; }virtual void func2() { cout << "Father::func2" << endl; }virtual void func3()…

一文彻底理解大小端和位域 BIGENDIAN LITTLEENDIAN

一文彻底理解大小端和位域 为什么有大小端 人们一直认为大道至简&#xff0c;就好像物理学上的世界追求使用一个理论来统一所有的现象。为什么cpu存在大小端之分&#xff0c;一言以蔽之&#xff0c;这两种模式各有各的优点&#xff0c;其各自的优点就是对方的缺点&#xff0c…

【C++学习】list的使用及模拟实现

&#x1f431;作者&#xff1a;一只大喵咪1201 &#x1f431;专栏&#xff1a;《C学习》 &#x1f525;格言&#xff1a;你只管努力&#xff0c;剩下的交给时间&#xff01; list的使用及模拟实现&#x1f63c;构造函数&#x1f435;模拟实现&#x1f63c;迭代器&#x1f435;…

[软件工程导论(第六版)]第6章 详细设计(复习笔记)

文章目录6.1 结构程序设计6.2 人机界面设计6.3 过程设计的工具6.3.1 程序流程图&#xff08;程序框图&#xff09;6.3.2 盒图&#xff08;N-S图&#xff09;6.3.3 PAD图&#xff08;问题分析图&#xff09;6.3.4 判定表6.3.5 判断树6.3.6 过程设计语言6.4 面向数据结构的设计方…

Spring Cloud Nacos实战(二)- 服务提供者注册

Nacos服务提供者注册 Nacos代替Eureka ​ Nacos可以直接提供注册中心&#xff08;Eureka&#xff09;配置中心&#xff08;Config&#xff09;&#xff0c;所以它的好处显而易见&#xff0c;我们在上节课成功安装和启动了Nacos以后就可以发现Nacos本身就是一个小平台&#xf…

解决IDEA报错:无效的目标发行版: 17

解决IDEA报错&#xff1a;无效的目标发行版: 17 目录解决IDEA报错&#xff1a;无效的目标发行版: 17报错由来解决报错【1】检查setting设置&#xff0c;查看编译器编译模块的编译版本是否是你需要的【2】尝试去修改当前项目的启动设置&#xff0c;设置JRE为你需要的版本。【3】…

odoo如何完成员工借款、报销、归还余款的会计操作?【业财一体】

ODOO中如何实现财务场景&#xff1a;一个员工从公司借款1000元&#xff0c;然后用这个借款&#xff0c;支付了电费500元&#xff0c;然后又归还剩余500元呢&#xff1f; 一、基本流程如下&#xff1a; 二、基础科目的设置 1.1 预付账款科目&#xff1a;设置在 产品【Employee…

DQL 多表查询

1、多表关系 一对多&#xff08;多对一&#xff09; 案例: 部门 与 员工的关系 关系: 一个部门对应多个员工&#xff0c;一个员工对应一个部门 实现: 在从表的一方建立外键&#xff0c;指向主表一方的主键 多对多 案例: 学生 与 课程的关系 关系: 一个学生可以选修多门课程&am…

Revisiting Distributed Synchronous SGD 带有Back-up机制的分布式同步SGD方法 论文精读

论文链接&#xff1a;Revisiting Distributed Synchronous SGD ABS 本文介绍了用于分布式机器学习的同步和异步SGDSGDSGD&#xff0c;同时指出各自的缺点&#xff1a;stragglersstragglersstragglers和stalenessstalenessstaleness。 同时为了解决同步SGDSGDSGD存在straggle…