当前位置: 首页 > news >正文

6.3 使用 Swagger 生成 Web API 文档

第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 {@Beanpublic 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();}@Overridepublic 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 {@Beanpublic 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 从入门到实战》学习笔记

相关文章:

6.3 使用 Swagger 生成 Web API 文档

第6章 构建 RESTful 服务 6.1 RESTful 简介 6.2 构建 RESTful 应用接口 6.3 使用 Swagger 生成 Web API 文档 6.4 实战&#xff1a;实现 Web API 版本控制 6.3 使用 Swagger 生成 Web API 文档 高质量的 API 文档在系统开发的过程中非常重要。本节介绍什么是 Swagger&#xff…...

Day894.加锁规则的一些问题 -MySQL实战

加锁规则的一些问题 Hi&#xff0c;我是阿昌&#xff0c;今天学习记录的是关于加锁规则的一些问题的内容。 加锁规则&#xff0c;这个规则中&#xff0c;包含了两个“原则”、两个“优化”和一个“bug”&#xff1a; 原则 1&#xff1a;加锁的基本单位是 next-key lock。nex…...

【Flutter入门到进阶】Dart进阶篇---Dart异步编程

1 并行与并发的编程区别 1.1 并发与并行 1.1.1 说明 我们举个例子,如果有条高速公路 A 上面并排有 8 条车道,那么最大的并行车辆就是 8 辆此条高速公路 A 同时并排行走的车辆小于等于 8 辆的时候,车辆就可以并行运行。 CPU 也是这个原理,一个 CPU 相当于一个高速公路 A,核心数…...

点云配准方法原理(NDT、ICP)

配准是点云处理中的一个基础问题&#xff0c;众多学者此问题进行了广泛而深入的研究&#xff0c;也出现了一系列优秀成熟的算法&#xff0c;在三维建模、自动驾驶等领域发挥着重要的作用。 本文主要介绍粗配准NDT (Normal Distribution Transform) 与 精配准ICP (Iterative Cl…...

大规模 IoT 边缘容器集群管理的几种架构-0-边缘容器及架构简介

&#x1f4da;️Reference: IoT 边缘计算系列文章 什么是边缘容器&#xff1f; 边缘容器的概念 边缘容器是分散的计算资源&#xff0c;尽可能靠近最终用户或设备&#xff0c;以减少延迟、节省带宽并增强整体数字体验。 可以访问互联网的设备数量每天都在增加。有包括但不限于…...

代码随想录算法训练营第45天动态规划 背包基础 1 2、 416. 分割等和子集

文章目录01背包基础 &#xff08;二维数组&#xff09;思路递推公式初始化遍历顺序一维dp数组&#xff08;滚动数组&#xff09;一维数组的递推公式遍历顺序LeetCode 416. 分割等和子集思路总结01背包基础 &#xff08;二维数组&#xff09; 思路 根据动态规划五部进行分析&a…...

QT学习记录(六)类对象属性

类对象属性用来描述类对象的一些信息和当前的状态。类对象属性可以由类的编写者在编写类的时候定义&#xff0c;也可以由类的使用者在使用对象的时候定义。 由类的编写者定义 QPROPERTY()宏就是用来定义一个对象属性。 以第二行属性举例 QPROPERTY(bool enabled READ isEnabl…...

Spring Cloud Alibaba从搭建到源码完整进阶教程

微服务简介 Spring Cloud Alibaba 微服务简介 Nacos注册中心配置中心 Spring Cloud Nacos实战&#xff08;一&#xff09;- 下载和安装 Spring Cloud Nacos实战&#xff08;二&#xff09;- 服务提供者注册 Spring Cloud Nacos实战&#xff08;三&#xff09;- 服务消费者…...

Spring Cloud Nacos实战(一)- 下载和安装

Spring Cloud Alibaba Nacos下载和安装 Nacos介绍 ​ Nacos&#xff08;Naming Configuration Service&#xff09; 是一个易于使用的动态服务发现、配置和服务管理平台&#xff0c;用于构建云原生应用程序 ​ 服务发现是微服务架构中的关键组件之一。Nacos 致力于帮助您发现…...

深入理解设备像素比

文章目录参考描述像素分辨率显示分辨率图像分辨率物理分辨率分辨率单位&#xff08;仅部分&#xff09;DPIPPI设备像素比设备物理像素设备独立像素设备像素比产生放大与缩小尾声参考 项目描述关于物理像素、逻辑像素&#xff08;css像素&#xff09;、分辨率、像素比的超详细讲…...

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

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

shiro CVE-2020-13933

0x00 前言 同CVE-2020-1957&#xff0c;补充一下笔记&#xff0c;在CVE-2020-1957的基础上进行了绕过。 影响版本&#xff1a;Apache Shiro < 1.6.0 环境搭建参考&#xff1a;shiro CVE-2020-1957 0x01 漏洞复现 CVE-2020-13933中使用%3b绕过了shiro /*的检测方式&…...

斐波那契数列(递归+迭代)

目录什么是斐波那契数列递归写法使用递归写法的缺点迭代写法(效率高)什么是斐波那契数列 斐波那契数列&#xff08;Fibonacci sequence&#xff09;&#xff0c;又称黄金分割数列&#xff0c;因数学家莱昂纳多斐波那契&#xff08;Leonardo Fibonacci&#xff09;以兔子繁殖为例…...

2022黑马Redis跟学笔记.实战篇(六)

2022黑马Redis跟学笔记.实战篇 六4.7.达人探店功能4.7.1.分享探店图文1. 达人探店-发布探店笔记2. 达人探店-查看探店笔记4.7.2.点赞功能4.7.3.基于List实现点赞用户列表TOP104.7.4.基于SortedSet实现点赞排行榜4.8.关注列表4.8.1.关注列表实现原理4.8.2.添加关注1. 好友关注-关…...

Linux-VMware常用设置(时间+网络)及网络连接激活失败解决方法-基础篇②

目录一、设置时间二、网络设置1. 激活网卡方法一&#xff1a;直接启动网卡&#xff08;仅限当此&#xff09;方法二&#xff1a;修改配置文件&#xff08;永久&#xff09;2. 将NAT模式改为桥接模式什么是是NAT模式&#xff1f;如何改为桥接模式&#xff1f;三、虚拟机网络连接…...

vue3学习总结1

一.vue3与vue2相比带来哪些变化&#xff1f;a.性能的提升&#xff08;包括打包大小减少&#xff0c;初次渲染的速度加快&#xff0c;更新渲染速度加快&#xff0c;内存减少&#xff09;b.源码的升级&#xff08;响应式的原理发生了变化&#xff0c;由原来的defineProperty变成了…...

SpringBoot统一功能处理

一、统一用户登录权限验证 1.1Spring拦截器 实现拦截器需要以下两步&#xff1a; 1.创建自定义拦截器&#xff0c;实现 HandlerInterceptor 接⼝的 preHandle&#xff08;执行具体方法之前的预处理&#xff09;方法。 2.将⾃定义拦截器加⼊ WebMvcConfigurer 的 addIntercept…...

2022年3月电子学会Python等级考试试卷(五级)答案解析

目录 一、单选题(共25题,共50分) 二、判断题(共10题,共20分) 三、编程题(共3题,共30分) 青少年软件编程(Python)等级考试试卷(五级&#...

【C++】智能指针

目录 一、先来看一下什么是智能指针 二、 auto_ptr 1、C98版本 2、C11的auto_ptr 三、boost 库中的智能指针 1. scoped_ptr 2、shared_ptr&#xff08;最好的智能指针&#xff09; 四、C11中新提供的智能指针 unique_ptr shared_ptr std::shared_ptr的循环引用问题…...

Seata架构篇 - AT模式

AT 模式 概述 Seata AT 模式是一种非侵入式的分布式事务解决方案&#xff0c;Seata 在内部做了对数据库操作的代理层&#xff0c;我们使用 Seata AT 模式时&#xff0c;实际上用的是 Seata 自带的数据源代理 DataSourceProxy&#xff0c;Seata 在这层代理中加入了很多逻辑&am…...

【HarmonyOS 5.0】DevEco Testing:鸿蒙应用质量保障的终极武器

——全方位测试解决方案与代码实战 一、工具定位与核心能力 DevEco Testing是HarmonyOS官方推出的​​一体化测试平台​​&#xff0c;覆盖应用全生命周期测试需求&#xff0c;主要提供五大核心能力&#xff1a; ​​测试类型​​​​检测目标​​​​关键指标​​功能体验基…...

Linux相关概念和易错知识点(42)(TCP的连接管理、可靠性、面临复杂网络的处理)

目录 1.TCP的连接管理机制&#xff08;1&#xff09;三次握手①握手过程②对握手过程的理解 &#xff08;2&#xff09;四次挥手&#xff08;3&#xff09;握手和挥手的触发&#xff08;4&#xff09;状态切换①挥手过程中状态的切换②握手过程中状态的切换 2.TCP的可靠性&…...

基于Docker Compose部署Java微服务项目

一. 创建根项目 根项目&#xff08;父项目&#xff09;主要用于依赖管理 一些需要注意的点&#xff1a; 打包方式需要为 pom<modules>里需要注册子模块不要引入maven的打包插件&#xff0c;否则打包时会出问题 <?xml version"1.0" encoding"UTF-8…...

html-<abbr> 缩写或首字母缩略词

定义与作用 <abbr> 标签用于表示缩写或首字母缩略词&#xff0c;它可以帮助用户更好地理解缩写的含义&#xff0c;尤其是对于那些不熟悉该缩写的用户。 title 属性的内容提供了缩写的详细说明。当用户将鼠标悬停在缩写上时&#xff0c;会显示一个提示框。 示例&#x…...

Chromium 136 编译指南 Windows篇:depot_tools 配置与源码获取(二)

引言 工欲善其事&#xff0c;必先利其器。在完成了 Visual Studio 2022 和 Windows SDK 的安装后&#xff0c;我们即将接触到 Chromium 开发生态中最核心的工具——depot_tools。这个由 Google 精心打造的工具集&#xff0c;就像是连接开发者与 Chromium 庞大代码库的智能桥梁…...

论文阅读笔记——Muffin: Testing Deep Learning Libraries via Neural Architecture Fuzzing

Muffin 论文 现有方法 CRADLE 和 LEMON&#xff0c;依赖模型推理阶段输出进行差分测试&#xff0c;但在训练阶段是不可行的&#xff0c;因为训练阶段直到最后才有固定输出&#xff0c;中间过程是不断变化的。API 库覆盖低&#xff0c;因为各个 API 都是在各种具体场景下使用。…...

mac:大模型系列测试

0 MAC 前几天经过学生优惠以及国补17K入手了mac studio,然后这两天亲自测试其模型行运用能力如何&#xff0c;是否支持微调、推理速度等能力。下面进入正文。 1 mac 与 unsloth 按照下面的进行安装以及测试&#xff0c;是可以跑通文章里面的代码。训练速度也是很快的。 注意…...

【深度学习新浪潮】什么是credit assignment problem?

Credit Assignment Problem(信用分配问题) 是机器学习,尤其是强化学习(RL)中的核心挑战之一,指的是如何将最终的奖励或惩罚准确地分配给导致该结果的各个中间动作或决策。在序列决策任务中,智能体执行一系列动作后获得一个最终奖励,但每个动作对最终结果的贡献程度往往…...

Android Framework预装traceroute执行文件到system/bin下

文章目录 Android SDK中寻找traceroute代码内置traceroute到SDK中traceroute参数说明-I 参数&#xff08;使用 ICMP Echo 请求&#xff09;-T 参数&#xff08;使用 TCP SYN 包&#xff09; 相关文章 Android SDK中寻找traceroute代码 设备使用的是Android 11&#xff0c;在/s…...

在MobaXterm 打开图形工具firefox

目录 1.安装 X 服务器软件 2.服务器端配置 3.客户端配置 4.安装并打开 Firefox 1.安装 X 服务器软件 Centos系统 # CentOS/RHEL 7 及之前&#xff08;YUM&#xff09; sudo yum install xorg-x11-server-Xorg xorg-x11-xinit xorg-x11-utils mesa-libEGL mesa-libGL mesa-…...