本文将介绍下API可视化框架Swagger在SpringBoot框架中的整合流程,对在整合过程中遇到的问题进行讨论,并对Swagger2进行测试的一系列内容。
Swagger 是一个规范和完整的框架,用于生成、描述、调用和可视化 RESTful 风格的 Web 服务。总体目标是使客户端和文件系统作为服务器以同样的速度来更新。文件的方法,参数和模型紧密集成到服务器端的代码,允许API来始终保持同步。Swagger 让部署管理和使用功能强大的API从未如此简单。
在开始整合之前,需要先创建SpringBoot项目,本文所用到的工具及版本如下:
SpringBoot版本高于2.6时默认路径匹配方式为PathPatternMatcher,而Swagger2基于的是AntPathMatcher,会出现documentationPluginsBootstrapper'; nested exception is java.lang.NullPointer错误,这里需要千万注意两者的兼容性!!!
本文将使用Maven作为管理工具进行探讨。引入Swagger2有两种方式,分别为starter方式和原生Maven依赖方式。
Swagger2的依赖可到Maven仓库中找到,所用到的版本为,这里贴出依赖:
SpringForAll下的spring-boot-starter-swagger利用Spring Boot的自动化配置特性来实现快速的将swagger2引入spring boot应用来生成API文档,简化原生使用swagger2的整合代码。
在spring-boot-starter-swagger的GitHub页面有着超级详细的介绍以及整合教程,此处不再进行过多的赘述,有需要此方式整合的小伙伴请移步spring-boot-starter-swagger。
Lombok
除了swagger2的依赖和SpringBoot的依赖之外,我们再引入Lombok,来减少一些 get/set/toString 方法的编写,合理的使用前人做好的轮子:
当然,在使用IDEA创建项目的时候顺手引入Lombok也不是不行。
commons-lang3
commons-lang3中有大量的工具类,这里我们也引用进来:
此处依然是重点介绍原生Maven依赖方式整合,与Starter采取配置文件方式进行配置不同的是,原生方式需要使用配置类进行配置;
当然,在本文中我们也会将配置类与配置文件进行配合使用,同样可解决配置不够灵活的问题。
这里我们将Swagger2配置类所需的参数封装到Properties类中,在src/main/java的包中,创建config/properties包用于存放Properties类:
接下来配置application.yml或者application.properties配置文件,本文使用的是application.yml,此处是与Properties类一致的:
参数配置完后,进行Swagger2Config的配置,此处参考了spring-boot-plus的配置方式,进行了一些简化:
因为增强的配置较为简单,且使用增强效率更高,所以将此部分内容提前。不和前面的一起讲解的原因是为了更好地区分哪些是Swagger的哪些是knife4j的,更容易理解。
本文中我们整合knife4j作为Swagger的增强,在pom中添加依赖:
在application.yml中添加如下配置:
修改Swagger2Config,添加启用knife4j的相关注解:
对于knife4j更加详细的配置,自行按需到官网查询即可。
knife4j 2.0.6以上版本,无需使用@EnableKnife4j注解,直接在配置文件中配置knife4j.enable = true 即可。此处为了进行区分,使用2.0.2进行演示。
上述步骤完成后,基本上前期配置工作就结束了,可以直接浏览器访问:http://localhost:8080/swagger-ui.html ,出现以下界面表示配置成功:

因为配置了增强,则推荐使用knife4j进行查看,访问http://localhost:8080/doc.html ,出现如下界面则表示增强配置成功(在此页面前会有要求输入用户名密码的页面,按照配置中的填写即可):

此部分截图均为knife4j页面截图,显示效果和页面逻辑更加清晰
接下来我们创建Controller并声明一些接口进行测试,这里我们来通过对用户增删查改、头像上传、登录等功能的模拟,来全方位展示如何使用Swagger2。在类中出现的Swagger2注解,会在类后有相应的介绍(只对常用属性进行了介绍,若需要深层次研究,建议到官网查阅文档)。
这里实际上有几种情况需要加以区分:
- 入参是否为实体类
- 响应是否为实体类
简单分析,上述的几个Api接口中:
- 新增接口、修改接口、登录接口等入参为实体类,其余入参为非实体类
- 查找接口响应为实体类,其余响应为非实体类
根据不同的情况,使用不同的Swagger注解进行处理。
@ApiModel
@ApiModelProperty
最大/最小值([1, infinity] infinity或-infinity表示无限值)
required 标记该字段是否必需,默认false hidden 标记该字段是否隐藏,默认false
当使用实体类作为入参时,可使用上述注解对实体类进行修饰,以达到描述实体类参数的目的。
控制器这里,分情况进行分别讲解,首先是Controller控制器类的定义:
接下来是接口方法的定义,在本节开始处,我们就了解了接口方法的集中参数情况和响应情况,这里针对这几种不同的情况分别进行讲解。
- 实体类作为入参
新增接口、修改接口均为实体类作为入参的情况:
@ApiOperation
例如:即使在@Api(tags = '用户管理')定义了接口组,也可以在此注解内指定另一个接口组,如@ApiOperation(tags = '账号管理'),使此接口可以同时出现在这两个接口组(用户管理 和 账号管理)中
当实体类作为入参时,我们在上一部分【实体类】中已经介绍了相应的参数描述注解以及用法,除@ApiOperation外,此处不再对其他注解(@ApiModel、@ApiModelProperty)进行赘述。

- 非实体类作为入参
当非实体类作为入参时,又可以细分为以下几种情况:
- 普通查询参数
这里我们将查找某个用户的参数定义为普通参数的Api方法:
@ApiImplicitParams 和 ApiImplicitParam
[通常与入参名对应]
value 参数说明 required 标记该参数是否必需,默认false paramType 标记该参数的位置,包含path、query、body、form、header等几种情况
[一般情况下,body、form推荐使用实体类作为入参]

- 路径参数
当参数为路径参数时,@ApiImplicitParam的paramType取值应为path,同时,使用@PathVariable注解修饰该路径参数。
@PathVariable注解能够识别URL里面的一个模板,如上述接口的{id},并且标记该参数是基于该模板获取的,并不属于Swagger注解,此处不做过多介绍。

- header参数
当参数为路径参数时,@ApiImplicitParam的paramType取值应为header,同时,使用@RequestHeader注解对参数进行修饰,将参数的获取位置标记为从Header中获取,让SpringMVC能够正确的从Header中获取到参数。

- 文件参数
这里我们直接讲解一种复杂情况,即考虑同时包含文件参数和普通参数,在实际开发过程中按需修改即可。
对于非文件参数的普通参数,参照第一条【普通查询参数】中的声明方式即可;
对于文件参数,则需要使用@ApiParam对参数进行修饰;
@ApiParam
同样的,需要在参数上使用@RequestParam进行修饰。

这里插入一个解释,就是对于同时出现Swagger注解(一般以Api作为前缀)和非Swagger注解同时对参数进行修饰时,并不会彼此影响,Swagger注解只是用来对Api方法进行描述,并不会对该方法造成实质影响,
而例如@RequestParam、@RequestHeader在内的注解是决定SpringMVC是否能正确读取到参数的关键
这里对于两种注解之间的侵入性,掘金大佬1黄鹰在其源码剖析@ApiImplicitParam对@RequestParam的required属性的侵入性做了深入剖析,感兴趣的可以去看看
- 实体类作为响应
当实体类作为响应时,通常在实体类上的注解所生成的描述也会作为响应的描述出现,在此处不再进行赘述。

- 非实体类作为响应
我们对新增接口进行修改,在其方法上添加@ApiResponses来对响应进行描述:
需要注意的是,Swagger无法对非实体类响应进行详细描述,只能通过@ApiResponses和@ApiResponse描述响应码信息。同时,在以实体类作为响应时,同样可也以使用@ApiResponses和@ApiResponse。

在做前后端分离的应用时,后端接口通常会要求在Header中添加Token以保证安全性,这里我们依然是参考SpringBootPlus的处理方式,对Token进行处理。
需要注意的是,此处的Token处理是基于Swagger进行接口测试时的,并不是对接口如何增加Token进行讲解,只是对有Token的接口如何通过Swagger进行测试做出讲解。
思路是,在Swagger配置中添加默认的全局参数描述,对Token进行处理,这里我们默认Token信息附加在Header中。
首先在SwaggerProperties中新增以下内容:
随后在application.yml中对新增部分编写对应的配置项,这里贴出整体内容,自定义参数配置部分为新增内容:
这里可以根据不同的需求,配置多个自定义参数,这里只演示了Token一个参数,如果是多个参数的话,配置多个即可,如下:
接下来,我们在Swagger2Config中对Token参数进行处理,首先在Swagger2Config中添加如下方法,从application.yml中获取到配置的额外Token参数并进行封装:
随后修改createRestApi方法,在声明Docket的位置添加对额外参数的处理,添加后如下:
重启项目后,我们随意打开一个接口的文档,这里我们打开的是knife4j的页面,选择调试,在请求头部位置就可以看到Token的相关内容:

当然,在Swagger的原生界面也可以看到:

- dynamicbeam:swagger2常用注解API,来源 CSDN
- 随风行云:Spring Boot整合swagger使用教程,来源 CNBLOG
- 1黄鹰:源码剖析@ApiImplicitParam对@RequestParam的required属性的侵入性, 来源 掘金
- SpringBootPlus
版权声明:
本文来源网络,所有图片文章版权属于原作者,如有侵权,联系删除。
本文网址:https://www.mushiming.com/mjsbk/2881.html