
本节会为大家介绍,如何基于 Spring Boot 集成 Swagger Codegen 到我们的项目中去,以及 Swagger Codegen 快速入门相关知识点,希望通过本节讲解,大家可以对 Swagger Codegen 有进一步的认识。
重点讲解内容:
- 如何将 Swagger Codegen 集成到 SpringBoot 中去;
- Swagger Codegen 快速入门与使用技巧。
因为本套课程使用 Maven 包管理工具构建,所以在集成 Swagger Codegen 时我们需要如下两个步骤:
这里我将依赖放到了下方,同学们可以直接拷贝:
等待编辑器下载完成后,没有任何依赖报错,就说明我们已经将 Swagger Codegen 的依赖引入到了 SpringBoot 中去。
我们知道,Swagger Codegen 主要的作用,就是生成服务端和客户端的完整代码文件,所以,在将 Swagger Codegen 集成到 Spring Boot 中后,我们首先需要做的就是,对生成服务端和客户端的代码进行规则配置,即我们都需要生成什么样的服务端和客户端代码。
配置服务端和客户端的代码生成规则叫繁琐,所以我们选择常用的几个属性来进行演示。
配置服务端代码生成规则
在 Swagger Codegen 中,配置服务端的代码生成规则,需要用到 yml 配置源文件,所以需要对 yml 配置源的语法有一定了解和掌握,有不清楚的同学请自行查阅相关资料。
对于以上所使用的属性我们会在本节的后半部分进行详细介绍,这里大家可以先做简单的了解即可。
配置客户端代码生成规则
在 Swagger Codegen 中,客户端的代码规则是通过 json 文件来进行配置的,json 相信大家都很熟悉,这里就不再做相关介绍了。
代码解释:
basePackage :用于声明 Swagger Codegen 在生成代码时所扫描的路径。
configPackage :用于声明 Swagger Codegen 在生成代码时配置文件所在的目录。
dateLibrary :用于声明 Swagger Codegen 在生成代码时所用的语言。
language :用于声明 Swagger Codegen 在生成代码时所用的框架语言描述。
modelPackage :用于声明 Swagger Codegen 在生成代码时项目中实体所在目录。
完成上述配置之后,我们就可以使用 Swagger Codegen 来生成服务端和客户端代码。
在将 Swagger Codegen 的依赖引入到 Spring Boot 中去后,我们就可以使用 Maven 自带的命令来将上述配置信息分别生成服务端和客户端代码,命令如下:
首先,将上述配置好的文件利用 Swagger Codegen 来生成服务端和客户端代码
代码解释:
第一行,使用 generate 命令来将配置在 swagger.yaml 文件中的服务端代码进行生成。
第一行,使用 -c 参数,表明使用 json 配置文件,并且该配置文件的名称为 swaggerConfig.json。
第二行,使用 -l 参数,表明客户端所使用的语言为 spring 。
第二行,使用 -o 参数来指定代码最终的存放位置,server 表示将生成的代码存放到名为 server 的文件夹下。
然后我们使用 cd 命令来进到我们生成代码后所存放的目录:
最后我们将生成的代码打成 Jar 包:
这是 Maven 自带的打包命令,执行该命令之后,Maven 会默认读取项目中的 pom 文件中配置的打包规则,即 packaging 节点,如果该节点没有配置任何规则,则 Maven 会默认打成 Jar 包 (这里我们配置了 Jar)。
这样我们就可以在项目的 target 目录下,找到我们利用 Swagger Codegen 所生成的服务端和客户端代码的 Jar 包了,我们可以把该 Jar 包放到其他环境中使用,也可以供其他项目使用,这就是我们利用 Swagger Codegen 所生成的服务端和客户端代码的最终使用目的。
服务端
我们针对以上服务端配置的规则来介绍一下在 Swagger Codegen 服务端中经常使用的一些属性,同学在了解了这些属性之后就可以使用 Swagger Codegen 进行一些服务端代码的生成工作了。
代码解释:
swagger : 指名生成的服务端代码所使用的 Swagger 管理版本,这里只能写 2.0 。
info : 表示 Swagger Codegen 所生成的服务端代码的一些基本描述信息,上述包括 title (头信息) 、 description (文档描述) 、 version (文档版本)。
paths : 表示具体一个接口的路径信息。
get : 表示该接口的 http 请求类型,get 即为 Get 请求,同理 post 即为 Post 请求,以此类推。
tags : 表示该接口所属的分组。
operationId : 表示该接口的名称。
parameters : 表示该接口中的参数信息,上述包括 name (参数名称) 、 in (参数用途) 、type (参数类型) 、 required (参数是否必传,true 表示参数必传,默认为 false )。
responses : 表示该接口的返回信息,这里的 200 表示接口返回状态码,description 代表当接口返回状态码为 200 时的状态码描述信息,schema 中的 ref 属性统一表示当该接口返回 200 时重定向的地址或接下来要发生的动作。
客户端
针对 Swagger Codegen 中客户端代码的配置,在前面已经做了一些较为详细的介绍了,这里我就常用的客户端配置代码给上述内容做一个补充,同学们需要结合着来了解。
代码解释:
apiPackage : 表示需要生成的客户端代码的包位置。
artifactId 、 groupId : 类似于 Maven 中的依赖坐标,这里表示所生成的客户端代码的坐标信息。
hideGenerationTimestamp : 表示在生成客户端代码之后会隐藏生成代码的时间,这个配置可有可无。
服务端
我们在生成服务端代码时,不能盲目生成,如果已经有写好的接口文档,那么我们需要按照这个接口文档进行编写和配置,如果没有写好的接口文档,那么我们需要和产品经理进行都次反复的沟通之后才能开始编写和配置服务端信息,这样可以在很大程度上减少服务端配置文件修改的次数,同时也可以提高服务端生成代码的准确性,这点同学们需要注意。
客户端
在生成客户端代码时,我们需要和服务端的开发人员进行详细的沟通,确定代码生成范围以及所需要使用的代码,尽量避免生成多余的、无用的、低价值的代码,这样不仅仅浪费系统资源,同时也浪费了项目开发的时间,这点也需要同学们注意。

本小节从在 SpringBoot 中如何集成 Swagger Codegen 出发,详细介绍了如何在 SpringBoot 中将 Swagger Codegen 进行集成,以及在集成中容易出现的问题。在介绍完 Swagger Codegen 集成 SpringBoot 之后,针对零基础的同学,老师将在 Swagger Codegen 中使用的最多的属性单独拿出来做了介绍,旨在帮助同学们能够快速入门 Swagger Codegen。
各位同学在学习本小节内容时,希望各位可以跟着老师的节奏一行一行地把本小节中所将的代码都动手敲一下,这样可以加深自己对代码的理解程度,在实操时我们不能眼高手低,自己的实践结果才是最重要的。
大家好,今天为大家介绍 Swagger Editor。Swagger Editor 和 Swagger Codegen 不同,Swagger Editor 适用于一切规模的项目,话不多说,咱们直入正题。
什么是 Swagger Editor 呢?在 Swagger 官网中是这么介绍的:
Swagger Editor 是一个开源编辑器,我们可以在这个开源编辑器上设计、描述和记录我们的 API 信息,通过 Swagger Editor 这个开源编辑器进行配置而生成的 API 是符合 RESTFUL API 规范的,并且 Swagger Editor 这款开源编辑器支持 Swagger 2.0 版本和 RESTFUL API 3.0 版本。 —官网
注意:这里提到的 OpenAPI 其实就是我们所谓的 RESTFUL API 规范,关于 RESTFUL API 规范我们已经在 Swagger 简介这一小节中做了详细的介绍,有不清楚的同学可以到该小节了解,这里不再赘述。
通过上面的介绍,说白了,Swagger Editor 就是一款提供了可以直接设计、描述和记录项目中所有的接口为 RESTFUL API 文档的开源编辑器,可以帮助我们提升项目开发效率。
那么我们为什么要使用 Swagger Editor 呢?
对于任何规模大小的项目而言,无论是小项目还是大项目,都会涉及到项目接口的开发,而对于项目接口的管理,最常见的就是根据项目接口内容撰写项目接口文档,但是这种方式有一种显而易见的弊端。
当项目中接口开发的需求发生变化时,根据项目管理规范,我们需要首先修改之前撰写好的相应的接口文档,由于种种原因,导致我们的修改时机很慢而不能及时支撑该接口的修改交付工作,这就会产生冲突,就会不得已先进行接口的修改,后续再来修改接口文档了。
针对上述类似问题,如果我们使用 Swagger Editor 来对接口进行维护,就会大大降低这种问题出现的概率。
Swagger Editor 提供了强大的配置文件类型,例如我们熟知的 yml 配置源文件和少数的 json 配置源文件,针对这两种配置文件,Swagger Editor 内置了丰富的 RESTFUL API 属性,开发人员可以直接使用这些属性来描述项目中的接口信息,不需要专门再将接口修改为符合 RESTFUL API 规范而发愁了。
在第一章中,当我们在项目中集成了 Swagger 框架之后,运行项目之后会为我们生成 Swagger-ui 界面,我们都知道这个界面还是相对美观一些的,我们也可以直接在这个界面上浏览接口和其他信息。
Swagger Editor 在配置好之后的生成界面几乎是和 Swagger-ui 界面是一模一样的,而且 Swagger Editor 的生成界面允许我们边修改配置信息边查看修改结果,可以实时看到我们的修改结果。
这就表明,如果我们项目中的接口需求发生了变动,我们可以直接在 Swagger Editor 中修改相应的配置信息,并且可以实时看到修改结果,这对开发人员来说是一个’福音’。
学习 Swagger Editor 这个工具和 Swagger Codegen 一样,需要大家真实开发过项目并且对项目进行过简单的配置,并且使用的是 Java 7 或以上的 JDK 版本。
如果你是一名后端开发人员,那么相信你在学习 Swagger Editor 时会信手拈来。

Swagger Editor 其实就是一款可以为项目中的接口生成 RESTFUL API 规范界面的开源工具,其完善的 RESTFUL API 生成机制和美观的界面显示效果可以在提升项目接口的维护效率的同时增强接口文档的交互性,这也是 Swagger Editor 的核心魅力。
本节会为大家介绍如何在当下主流操作系统中安装 Swagger Editor 开源 API 配置工具。
重点讲解内容:
- 如何基于 Node 环境安装 Swagger Editor ;
- 如何基于 Docker 环境安装 Swagger Editor ;
- Swagger Editor 安装是否成功的必要性测试。
基于 Node 环境来安装 Swagger Editor ,是 Swagger Editor 官方推荐使用的第一种方式,通过 Node 来安装 Swagger Editor ,无论是 Windows 系统还是 OS X 系统,都要求电脑中首先要有 Node ,如果你的电脑中还没有 Node 环境,那么请先安装 Node 。
Node.js 是一个基于 Chrome V8 引擎的 JavaScript 运行时环境,同时提供了前台界面和后台服务的支持,而 Swagger Editor 的运行首先需要一个 http 服务器,所以在正式安装 Swagger Editor 时,我们首先需要安装一个 http 服务器。
在 Node 环境中,提供了很多 http 服务器的支持,例如:Express 、 http server 等。针对 Swagger Editor 的特点和后台服务器的适用条件,这里我们采用 http server 来当做 Swagger Editor 的服务器支持。
至于为什么选择 http server 来做后台服务器,这是不属于本节所介绍的内容,希望同学们可以在课下了解原因。
我们使用一下命令来在 Node 环境中安装 Http Server 服务器:
-g 表示全局安装 http-server 服务器,这样我们就可以不用专门去 http-server 服务器目录下启动该服务了。
我们看到如下提示信息就表明安装 http-server 服务器成功:

要想在 http server 服务器中安装 Swagger Editor ,需要我们首先将 Swagger Editor 的压缩包下载下来,这就相当于在安装 Swagger Codegen 时的 Jar 包。出于方便考虑,我将 Swagger Editor 的资源压缩包放到了我的 Git 上面,同学们可以通过访问以下链接获取:
https://github.com/SteafanMrZhou/MoocSwaggerWiki
在安装好 http server 服务器之后,我们将下载好的压缩包进行解压,在解压完成后我们输入以下命令来启动 Swagger Editor 服务:
我们看到下图提示信息则表明 Swagger Editor 服务已经安装成功并成功运行:

基于 Docker 环境来安装 Swagger Editor 是 Swagger Editor 官方提供的第二种方式,同样地,想在 Docker 中安装 Swagger Editor ,需要电脑中首先要有 Docker 环境。
关于 Docker 的安装过程以及基础知识,由于不是本节文章所需要介绍的内容,所以该方面的知识点希望同学们可以在课下了解。
众所周知,Docker 是一个容器服务,其是通过提供众多工具的镜像文件来将对应的服务集成到容器中,而且 Docker 官方整理了全球主流工具的镜像文件,并且将其放到了 DockerHub 上面。
所以,要想在 Docker 中安装 Swagger Editor ,我们首先需要从 Docker 官方的 DockerHub 上面将 Swagger Editor 的镜像文件拉取(下载)下来,在 Docker 容器中命令如下:
运行以上指令,等待 Swagger Editor 的镜像文件拉取完毕。
在 Swagger Editor 镜像拉取完毕之后,我们可以直接运行该镜像文件,如果运行成功,则表明 Swagger Editor 在Docker 环境中已经安装成功,运行 Swagger Editor 镜像文件的命令如下:
代码解释:
docker run -d -p 为固定写法,同学们目前不用知道表示什么意思,只需要知道这是运行镜像文件的固定命令即可。
80:8080 表示将 Docker 容器中的 Swagger Editor 服务映射到我们本机的 80 端口上,
swaggerapi/swagger-editor 表明我们所运行的镜像文件的名称。
在运行 Swagger Editor 服务时,如果已经提供了 json 文件,那么我们可以使用以下命令进行启动,从而修改该 json 文件:
在运行上述指令后,我们等待 Swagger Editor 镜像文件在 Docker 容器中运行完毕即可。
无论使用哪种环境安装的 Swagger Editor ,检测安装是否成功的标志已经在上述内容中提及,接下来我们需要做的是访问我们已经安装并运行的 Swagger Editor 服务。
一般而言,当我们的 Swagger Editor 服务启动之后,可以通过以下方式来访问:
如果在启动 Swagger Editor 服务的时候,你自定了服务的端口,则要通过以下方式来访问:
在浏览器中输入访问地址之后,我们可以看到如下 Swagger Editor 的引导界面就表明 Swagger Editor 已经成功安装并且可以正常使用了:

Tips :
- 在安装 Swagger Editor 之前,都需要我们首先将 Node 环境和 Docker 环境安装好,这是使用 Swagger Editor 的前提,在安装 Node 环境和 Docker 环境时,一定要注意版本的差异,一本推荐使用最新版本来安装
- 一般在使用 Swagger Editor 的时候,很多情况都需要我们从零开始配置我们的 API 配置文件,很少情况会在基于已经配置好的 API 配置文件上进行修改。
- 由于种种原因导致安装 Swagger Editor 失败的同学,可以通过访问 Swagger 官方提供的 Swagger Editor 在线使用地址(https://editorhttp://www.360doc.com/content/22/0505/18/)来了解 Swagger Editor:
5.小结

本小节针对当下主流环境,分别详细介绍了在 Node 环境和 Docker 环境中安装 Swagger Editor 的步骤,以及在安装时候容易出现的问题,针对 Swagger Editor 所需的压缩文件,考虑到自行下载可能下不动的情况,所以又额外提供了相关资源连接,同学们可以直接下载。
在安装 Swagger Editor 时,由于用到了 Node 环境和 Docker 环境,所以需要同学们先了解一下上述环境的基本使用方法,这样才可以随心应手的使用 Swagger Editor。
本节会为大家介绍,如何基于 Spring Boot 集成 Swagger Editor 到我们的项目中去,以及 Swagger Editor 快速入门相关知识点,希望通过本节讲解,大家可以对 Swagger Editor 有进一步的认识。
重点讲解内容:
- 如何将 Swagger Editor 集成到 SpringBoot 中去;
- Swagger Editor 快速入门与使用技巧。
因为本套课程使用 Maven 包管理工具构建,所以在集成之前需要我们先将 Swagger Editor 的依赖引入到项目中去,但是很不幸,Swagger Editor 官方并没有提供对 Maven 的支持,所以我们就不能通过 Maven 的方式将 Swagger Editor 集成进来。
难道就没有办法将 Swagger Editor 与 SpringBoot 结合使用了吗 ?
俗话说,方法总比困难多,所以这里我们另辟蹊径,通过使用配置 yml 文件的方式将 Swagger Editor 集成进来,话不多说,我们直入正题。
我们都知道,在 SpringBoot 项目中,一般的项目配置文件是如下图所示的 applicaiton.properties 文件:

applicaiton.properties 文件是传统的项目配置文件,无论使用 Spring 的哪种框架,我们都可以在项目中使用 applicaiton.properties 文件,但是这种文件有一种弊端,就是我们项目的配置信息在该文件中显示的有点乱,不利于开发人员维护,通常一行配置语句会显得很长,降低了项目配置文件的可阅读性。
正如此,在经过时代变迁之后,终于迎来了 YAML 配置源文件的到来,YAML 文件不单单只是一种平台上的配置源文件,他可以支持 Java 、 Python 、 PHP 等主流语言使用,并且各种语言平台都有对应的转换配置语法对应关系表,编写起来简单方便,且利于阅读。
将 applicaiton.properties 文件 修改为 YMAL 配置源文件的方式非常简单,我们只需要将 applicaiton.properties 文件的后缀 .properties 修改为 .yml 就可以了。
在修改完之后,我们就不能使用 applicaiton.properties 文件的语法了,我们需要使用 YMAL 配置源文件的语法才行。
在集成 Swagger Editor 到 SpringBoot 中时,为什么我们需要将 SpringBoot 项目的配置文件 applicaiton.properties 来修改成 YAML 配置源文件呢 ?这是因为我们的 Swagger Editor 只支持以 .yml 文件格式结尾的配置文件来编写 Swagger Editor ,这也是我一再强调 YAML 配置源文件的原因。
在修改好配置源文件之后,接下来我们需要编写配置源文件,并且在编写完配置源文件之后,我们需要将该配置源文件进行重命名,重命名的规则一般都是项目名称 + Swagger Editor + 配置源文件版本号。
简易配置 Swagger Editor 源文件
Swagger Editor 的配置源文件我们在 Spring Boot 集成 Swagger Codegen 小节中做了简短的介绍:就是我们在配置 Swagger Codegen 服务端代码生成规则那里的服务端代码其实就是 Swagger Editor 配置源文件的一部分,也就是说Swagger Codegen 服务端的代码生成规则是通过 Swagger Editor 配置源文件来实现的。
所以,在掌握了 Swagger Editor 的基本语法和使用技巧之后,我们就可以在编写好 Swagger Editor 配置源文件之后来生成我们项目的服务端代码,可谓是一举两得,这也是 Swagger 官方为我们所考虑的一方面。
还是那句话,在 Swagger Editor 中,配置 Swagger Editor 需要对 yml 配置源文件有一定的了解和使用,所以,有不清楚的同学请自行查阅相关资料。
接下来我们通过 Swagger Editor 官方的 Demo 来为大家配置 Swagger Editor 。
Swagger Editor 基本配置信息
Swagger Editor 接口配置信息
对于以上所使用的属性我们会在本节的后半部分进行详细介绍,这里大家可以先做简单的了解即可。
在配置好 Swagger Editor 基本配置信息和 Swagger Editor 接口配置信息之后,我们就可以在项目中生成 Swagger-UI 界面了。
我们生成 Swagger-UI 界面需要依赖 http-server ,我们在编辑器的控制台中输入以下命令即可:
即我们为 Swagger Editor 指定需要使用的 .yml 配置源文件即可,生成后的界面如下图所示。

接下来,我们针对上述 Swagger Editor 配置源文件中的属性来为大家介绍每个属性都代表什么意思,都用来做什么,以及在使用 Swagger Editor 时的一些使用技巧和注意事项。
Swagger Editor 基本配置信息
代码解释:
swagger : 指名所使用的 Swagger 管理版本,这里只能写 2.0 。
info : 表示 Swagger Codegen 所生成的 Swagger-UI 界面的一些基本描述信息,上述包括 title(头信息) 、 description(文档描述) 、 version(文档版本) 、termsOfService(服务团队) 、 contact(联系人) 、 license(协议或条款)。
host : 表示生成的 Swagger-UI 所在的主机,即 Swagger-UI 界面生成之后是放在什么位置的。
basePath : 表示访问 Swagger-UI 生成界面的具体路径。
tags : 表示对 Swagger-UI 文档中的接口进行分组。
tags-description : 对接口分组添加描述信息。
tags-externalDocs : 指定接口分组额外的说明文档,这里没有指定。
tags-url : 表示对该接口分组添加额外的描述信息地址。
schemes : 表示整个 Swagger-UI 界面上的接口所使用的网络协议,这里指名可以使用 http 和 https 网络协议。
Swagger Editor 接口配置信息
由于篇幅有限,Swagger Editor 接口配置信息部分的属性介绍在 SpringBoot 集成 Swagger Codegen 这一小节中有详细的说明,同学们可以去该小节了解。
我们在使用 Swagger Editor 时,一般都是在没有借口文档的情况下进行,所以这就要求我们对接口所开展的业务有很清晰的了解才行。
在 Swagger Editor 中,我们会对不同属性编写不同的描述信息,而涉及到名字的属性一定要注意,例如:title 属性,在对这一类型属性进行描述时,我们应该根据项目需求文档来进行描述,不能自己随意起名字,只有按照项目需求文档来描述的 Swagger Editor 属性才能说是准确的,是服务于当前项目的。
即使我们把 Swagger Editor 引入到了 SpringBoot 项目中去,但是如果想要运行 Swagger Editor ,我们还是要依赖于 http-server ,因为 Maven 并没有提供对 Swagger Editor 的支持服务。

本小节对在基于 SpringBoot 环境下如何集成 Swagger Editor 进行了详细的介绍,通过对分解的集成实现思路的详细介绍以及为何要采用该种实现思路的原因都做了详细的介绍和补充说明,在文章最后还详细阐述了 Swagger Editor 在实际项目开发中使用的一些注意事项,旨在帮助大家在了解了 Swagger Editor 基本定义之后可以快速入门 Swagger Editor。
在集成 Swagger Editor 时,还需要注意 Swagger Editor 与 Swagger Codegen 之间的共同点与不同点,注意区分和体会他们的应用场景和使用目的,这样在实际开发中才能根据不同场景来选择合适的工具来完成工作。
大家好,今天为大家介绍 Swagger 生态体系中的最后一部分内容- Swagger 辅助工具。该部分内容主要介绍 Swagger 官方提供的辅助工具,他们分别是:Validator、Parser、Inflector。
在本节中我会对这三个辅助工具进行一些简单必要的介绍,由于篇幅原因,不会详细介绍他们应该怎么用,如有需要请自行查阅相关资料。
本节主要内容如下:
- Swagger Validator 的定义及简单使用;
- Swagger Parser 的定义及简单使用;
- Swagger Inflector 的定义及简单使用。
什么是 Swagger Validator 呢?在 Swagger 官网中是这么介绍的:
Swagger Validator 是一个 Swagger 验证器,用于验证你的 Swagger 文档。 —官网
我们来看一下 Swagger Validator 官方提供的一款在线体验平台(https://validatorhttp://www.360doc.com/content/22/0505/18/):


从图中我们可以看到,Swagger Validator 的显示界面非常类似于 Swagger-UI 的显示界面,风格和排版都很相似,那么我们应该怎么来用呢 ?
根据官方文档我们不难看出,Swagger Validator 就是一个校验 Swagger 文档的工具,那么我们应该怎么来用呢 ?
我们可以在上述截图中看到一个 Validator 字样的单词,在这个单词下放,是 Swagger 官方为我们提供的 Swagger 文档中接口请求规范,以及接口定义要求。
就是说,我们可以把我们编写的 Swagger 文档和 Swagger Validator 官方校验界面做一个比较,看一下是否符合 Swagger Validator 官方的要求,校验的范围就包括:接口请求定义是否符合规范、接口返回值是否符合规范等,而进行校验的方式就是通过对比 Validator 下的内容。
如果在校验后发现,我们的 Swagger 文档有部分内容不符合 Swagger Validator 官方所展示的,那么我们就需要对这一部分进行修改,直至符合 Swagger Validator 官方的要求才行。
什么是 Swagger Parser 呢?在 Swagger 官网中是这么介绍的:
Swagger Parser 是可以将 Java 项目中的 POJO 文件都解析成符合 OpenAPI 规范的类,同时它也提供了一个简单的框架来将不同平台的 POJO 文件都转换为统一的 Swagger 对象,来使整个 Swagger 工具链变得可用。 —官网
我们可以这样简单的理解:Swagger Parser 是专门服务于 POJO 文件的一个工具包,他可以将来自不同平台中的不符合 OpenAPI 规范的 POJO 文件都解析成符合统一规范的格式,使得我们在任何平台上都可以正常的使用 Swagger 。
由于 Maven 官方提供了对 Swagger Parser 的支持,所以我们只要将 Swagger Parser 的 Maven 依赖引入到我们项目中去就可以使用了:
通过配置以下代码我们就可以来读取符合 OpenAPI 规范的文件了:
- 第1-2行,我们在项目中引入使用 Swagger Parser 必须的包。
- 第3-4行,我们使用 read 方法来读取 Swagger 官方的符合 OpenAPI 规范的文件。
什么是 Swagger Inflector 呢?在 Swagger 官网中是这么介绍的(由于介绍太长,这里只选择主要部分说明):
Swagger Inflector 是可以使用 Swagger 规范去驱动一种 API 的实现,并且你拥有全部的权限在实现过程中进行修改。 —官网
也就是说,Swagger Inflector 是一款可以使用 Swagger 规范去生成符合 Swagger 规范的 API 工具,并且可以在实现过程中针对不符合规范的地方进行完全的修改,最后使之符合 Swagger 的规范。
由于 Swagger Inflector 的使用相对非常少,并且如果想使用 Swagger Inflector ,那么你的项目就必须使用一种框架才能将 Swagger Inflector 集成进去,这个框架就是 Jersey 。
关于 Jersey ,这里就不多说了,大家只需要这是一款小众框架就行了,现在没有完全被淘汰,还有很多小公司仍在使用。
那么,在将 Jersey 集成好之后,我们就可以在 Jersey 生成的 web.xml 文件中添加如下配置来使用 Swagger Inflector 了:
Tips :
- Swagger Validator 、Parser 、Inflector 都是 Swagger 官方提供的辅助工具,主要目的都是为了使 Swagger 相关文件更符合 Swagger 的规范,这三个工具他们各司其职,同学们在使用时注意区分适用场景。
- 这三个辅助工具虽然在实际项目开发中很少使用,但是他们也属于 Swagger 整个系统中的一部分内容,所以要想系统学号和用好 Swagger ,那么该部分内容是不可获取的。

我们在学习 Swagger Validator 、Parser 、Inflector 时一定要注意他们的适用场景,区分他们之间的共同点和不同点,在学习本节内容时自己可以动手实践一下,这样才能更好地掌握。
Swagger Validator 、Parser 、Inflector 这三款辅助工具的介绍作为 Swagger 整套课程体系的最后一节内容,老师从他们的不同使用业务场景出发,介绍了他们最简单的使用方法,希望通过本节内容的介绍,同学们可以对这三款辅助工具有一个新的认识。
同学们,写到这里,Swagger 系统知识点就给各位介绍完毕了,在这中间感谢各位的支持,江湖路远,我们有缘再见!
上一节

本节会为大家介绍 Swagger 生成界面,即 Swagger-UI 界面的基础使用方法,包括界面基本元素讲解、界面接口内容讲解以及如何使用 Swagger-UI 界面进行必要的接口调试。
关于如何集成 Swagger 以及如何查看 Swagger-UI 界面请参考上一章节中的 'SpringBoot 集成 Swgger-UI’ 小节内容,本节不再赘述。
重点讲解内容:
- Swagger-UI 界面所有基本元素,界面接口基本内容;
- 基于 Swagger-UI 界面进行必要的接口调试。
掌握 Swagger-UI 界面的使用方法是使用 Swagger 进行接口调试的基本组成方式,所以请大家重点掌握该部分内容。
在本部分我将以图文并茂的方式介绍在 Swagger-UI 界面上的基本元素,这些基本元素在界面的不同区域,是界面的基本组成元素。
我将按照 Swagger-UI 界面基本元素所处的不同区域依次介绍每个基本元素的含义和作用,下面我们都来看看有哪些基本元素以及他们所发挥的作用吧!

在配置好 Swagger 之后,我们在浏览器地址栏中输入项目中 Swagger-UI 界面的路径即可看到如上图所示的界面,这就是 Swagger-UI 的核心界面,也是我们使用最多的界面,项目中所有的接口都会在该界面上显示。
我们从上到下,依次进行介绍:
在顶部栏区域的最左侧是 Swagger 的 Logo 图标,我们不需要关心。
在顶部栏区域的最右侧是一个 Explore 按钮,该按钮的作用就是刷新 Swagger-UI 界面,在我们点击时就会刷新,没有其他用途。
在 Explore 按钮的左侧,是 Swagger-UI 加载 html 界面模板的区域,这是一个下拉框,可以选择我们自定义的界面显示。
在中部区域可以看到只有最左侧有内容,在右侧是没有任何内容显示的。
在中部区域可以看到一行加粗加黑的字体:“immooc-Swagger-UI-Studying”,这里是用来描述 Swagger-UI 界面所显示的主要内容,一般使用我们的项目名称来描述。
在加粗加黑字体的下方是一行黑色的小字体:“Created by Steafan”,这里是用来描述 Swagger-UI 界面的作者信息,一般是接口维护人员或者接口开发人员。
在底部最开始的地方,我们可以看到 “user:User Controller” 等字样,这是我们使用 @ApiOperation 注解的 tags 属性来为接口描述的分组名称,当我们点击 user 之后,字体会加粗显示,同时会列出所有属于该 user 分组的接口列表,如下图所示:

而 User Controller 则是我们这些接口所属的 Java 类的名称,这里的名称通过 @Api 注解描述。
在最底部区域可以看到 “BASE URL” 字样,这里的 base url 指的是 Swagger-UI 界面的访问路径,即:http://host:port/imooc/imooc-user-service/swagger-ui.html (这里的路径是自己配置的),右侧的 API VERSION 代表当前接口的版本。
在上述部分,我们介绍了 Swagger-UI 界面的所有基本元素,接下来我们来看看我们开发的接口在 Swagger-UI 界面中都有哪些内容。
在接口列表中,我们点开之前一直使用的用户登录接口 (login.do),会显示出接口的所有内容信息,由于接口内容太长,所以我们分块进行讲解:

我们可以看到在图片的最上方是一个接口标题,其中,POST 代表接口的请求类型,/user/login.do 代表接口的地址以及接口名称,最右侧的用户登录就是我们使用 @ApiOperation 注解的 value 属性所描述的接口的作用。
Response Class 表示接口的响应信息,即我们请求接口时返回的响应内容,Status 200 表示该接口是可以正常使用的(接口状态的编码及意义请自行查阅,本节不做介绍)。Example Value 是 Swagger 自动生成的接口返回信息的模板,这也是接口真正的返回信息。
Response Content Type 是一个下拉框,表示接口所返回信息的类型,这里是 Swagger 的默认设置,表示返回什么类型的信息都可以。

Parameter 列表示接口的请求字段名称,就是接口的请求值,这里描述的是一个 user 对象。
Value 列表示请求接口的真实字段值,就是我要使用这个接口都需要传递哪些参数。该列还有一个关键内容:Parameter content type ,这是一个下拉框,表示我们传递参数的请求头信息,这里的 application/json 表示我们以 json 的形式进行传递(json 表示什么意思请自行查阅,本节不做介绍)。
Description 列表示对接口请求值的描述信息,就是我们在向这个接口传递参数的时候的一些注意事项,这里没有描述,所以 Swagger 默认使用了字段名称来描述。
Parameter Type 列表示接口的请求字段的类型,就是我需要向这个接口传递什么类型的参数,这里是 body ,表示我们传递的请求字段的类型是一个对象,这是我们自己设置的。
Data Type 列表示请求该接口的真实字段值,就是我要向接口传递的具体参数值,由 Swagger 默认生成,和 Value 列相对应,我们可以直接复制该列的 Example Value 的内容粘贴到 Value 列中来进行接口调试,这样就不用我们在 Value 列手动去输入字段值了。

HTTP Status Code 列表示接口请求返回的状态编码,不同的编码会对应不同的意义,和 Reason 列相对应:201 - 表示已建立接口连接,401 - 表示接口无权限访问,403 - 表示接口访问被禁止,404 - 表示在当前路径下找不到该接口,接口无法返回信息。
- Response Model 列表示我们使用 @Response 注解定义的内容,表示接口的响应策略,这里只需要知道表示什么意思就行,一般很少使用。
Headers 列表示接口返回信息的响应头类型,这里我们简单了解就行。
在左下角有一个 Try it out! 按钮,该按钮就是用来调试接口的。具体如何调试接口本节不做介绍,我会使用专门一节的内容来介绍如何使用 Swagger-UI 进行接口调试。
调试的目的:
我们都知道,在实际项目开发中,当我们的接口开发完毕之后需要进行一些必要的自行测试,目的就是来看看我们自己所开发的接口有没有低级错误和基本错误,在进行自测之前,我们先来了解一下什么是低级错误,什么是基本错误。
低级错误一般是指接口的请求方法没有按照接口文档或者需求来规定,对外暴露的接口地址并不能被请求到。
基本错误一般是指接口中的参数类型在开发时没有根据接口文档或者需求来定义,接口的返回数据中由于程序引起的返回空值或没有返回任何内容。
调试的方法:
在上述内容中,我们已经对 Swagger-UI 界面进行了基本详细的介绍。我们以一个用户登录接口为例,来看看如何在 Swagger-UI 界面上进行接口自测试。
这一步很简单,只需要我们在浏览器中输入 Swagger 生成的 Swagger-UI 界面地址即可,在浏览器加载完毕后,我们可以在界面上看到我们项目中的所有接口,在这些接口列表中需要测试哪个接口,我们只需要点击接口名称即可,如下图所示:

针对接口的内容区域,我们已经在上述内容中进行了详细介绍,这里直接步入正题。

点击接口内容区域的 try it out 按钮,将锁定的 Example Value 区域解锁,解锁之后的界面如上图所示。
- 我们需要在标签 1 的位置填充接口的请求参数。
- 我们需要在标签 2 的位置选择请求接口的请求头类型,一般都为 application/json 类型,这也是 Swagger 默认自带的类型,一般不需要再次选择。
这里我们就以截图中的测试数据为例:
在两个位置的内容都填充好之后,我们点击 Execute 按钮来执行我们的接口请求。等待片刻之后我们就会在接口内容区域的最下方看到我们请求所对应的接口响应结果:

- 红色箭头指向的地方表明我们已经点击了 Execute 按钮,即请求已经发送成功了。
- 标签 1 区域表明接口的请求路径 Url ,我们可以在这个地方检查是否和接口文档或需求所要求的接口地址一致。
- 标签 2 区域表明接口的响应返回结果,分为 Code 和 Details 区域,其中,Code 表明返回状态码,这里是 200 表明接口请求成功,Details 表示请求接口成功时所返回的响应结果。
接口自测试总结
在执行完上述两个步骤之后,我们就完成了一个接口的自测试,通过在 Swagger-UI 界面上进行接口自测试我们可以很清楚地看到接口的路径是否正确、接口的请求参数是否正确、接口的返回结果是否正确,通过这种方式我们很好地降低了一个接口的低级错误和基本错误,这在实际项目开发中是非常重要的。

本小节对 Swagger 三剑客之一 Swagger-UI 生成界面进行了详细的讲解,采用图文并茂、要点击破的方式对生成界面的每一个基本元素和接口内容都做了详细的讲解和必要的补充,针对需要重点掌握的内容使用了加粗显示,旨在帮助大家在理解 Swagger-UI 生成界面基本概念的同时也要懂得如何使用 Swagger-UI 生成界面来查看接口基本内容、接口要点信息等。
在介绍完 Swagger-UI 生成界面的基本元素以及接口基本内容区域之后,我们还结合一个用户登录接口就如何基于 Swagger-UI 生成界面进行接口调试做了详细的介绍,通过分步实现的顺序对每一步骤中需要注意的地方单独做了讲解。
希望各位同学在学习本小节内容时可以结合自己的项目或者自己创建的 Demo 案例来学习,这是掌握本节内容最好最快的方式。
本节会为大家介绍如何自定义 Swagger-UI 生成界面。
一般来说,Swagger 为我们自动生成的界面就足以满足我们绝大多数的需求,然而避免不了需要根据业务需求定制 Swagger-UI 界面的情况,尽管这种情况很少。
本节作为 Swagger 三剑客之一 Swagger-UI 的组成部分,将会为大家介绍 Swagger-UI 主流的自定义实现方案,由于本套课程适合于初学者,所以很复杂的实现方式以及一些实现原理将不予介绍。
重点讲解内容:
- 主流自定义 Swagger-UI 界面实现方案对比;
- 基于 Swagger-ui-layer 实现自定义 Swagger-UI 界面。
对于自定义 Swagger-UI 界面的实现,目前有两种方法用得最多:
由于 Swagger-UI 的解析原理是通过访问 v2/api-docs 路径下的 html 文件来解析 json 数据,使用这种方法我们首先需要自定义 html 文件,然后将 v2/api-docs 的访问路径指向我们自定义的 html 文件所在地址即可。
这种方法实现起来难度较大,并且需要开发人员掌握一定的前端 html 相关知识,还需要开发人员有一台属于自己的服务器来部署自定义的 html 文件,对绝大多数开发人员并不推荐使用该方法。
出于强烈的 Swagger-UI 界面自定义需求,Swagger 的社区开始活跃了起来,前两年就可以在 Swagger 社区中看到 Swagger-ui-layer 这一名词。Swagger-ui-layer 是一款专门针对自定义 Swagger-UI 界面而开发的工具包,其支持 Java 平台等其他主流平台集成使用。
使用 Swagger-ui-layer ,我们只需要进行两步操作,即可完成自定义 Swagger-UI 界面的功能,这种方式集成方便,配置简单,是业界用得最多的一种方式,也是我推荐使用的一种方式,本文就是使用 Swagger-ui-layer 来介绍如何自定义 Swagger-UI 界面。
下面就让我们来看一下如何使用 Swagger-ui-layer 来实现自定义 Swagger-UI 界面吧!
使用 Swagger-ui-layer 来自定义 Swagger-UI 界面需要两步骤即可完成:
我们都知道,向项目中集成依赖的方式有很多种:我们可以直接把依赖包拷贝到项目中去,也可以通过主流包管理工具将依赖进行统一管理,从而将依赖集成到项目中去,本套课程在开篇时已经说明使用 Maven 包管理工具来构建项目,所以这里关于 Maven 的相关知识不再介绍,有不知道同学可以自己去查一下相关资料。

出于方便考虑,上述依赖截图对应下面依赖代码:
代码解释:
上方的依赖为 Swagger 的依赖,下放的依赖为 Swagger-ui-layer 的依赖,同学们可以直接将上述两个依赖直接拷贝到自己项目的 pom 文件中去。
在将依赖拷贝到项目的 pom 文件中去后,等待依赖加载完毕即可。
这里我们需要对上一章节中介绍的 Swagger 配置类进行一些必要的修改,修改好的配置类代码如下:
代码解释:
第 2 行,我们通过 DocumentationType.SWAGGER_2 属性声明项目中所使用的接口文档类型是 Swagger 2 版本的,这是必须的。
第 9 行,我们通过向 apiInfo 方法将我们自定义的 Swagger 界面描述信息填充到 Swagger-UI 中去。
第 12 行,在 productApiInfo 方法内部,我们对 Swagger 界面上所展示的信息进行一些必要的描述。
以上就是配置类的最关键的三个部分,当我们配置完这些属性之后,启动我们的项目即可看到界面效果。
显示效果:

Tips :
- 注意 Swagger-ui-layer 开源工具的版本和 Swagger 版本的区别,虽然官网上说 Swagger-ui-layer 的版本并不会因为 Swagger 版本的变迁而受到影响,但是这里还是要说一句:如果是 Swagger 2.0 或以上版本,则请使用 Swagger-ui-layer 的最新版本 1.1.3。
- 一般情况下,我们不需要针对 Swagger-UI 界面进行自定义配置,如有特殊要求,例如公司或企业定制时才会用到,然而,使用 Swagger-ui-layer 是最常用的方案。
- 本节只是对 Swagger-ui-layer 进行一个相对简单的介绍,如果同学们感兴趣可以去 Swagger-ui-layer 的 github 上获取更多相关资料,出于对开源贡献者的尊敬,这里附上链接地址:https://github.com/caspar-chen/swagger-ui-layer 。

本小节针对如何自定义 Swagger-UI 界面做了详细的介绍,从当前可用的两个主流方案开始,通过对比当下主流方案的区别,选择了适合本课程的实现方案,同时针对该实现方案在具体实操环节中容易出现的问题做了必要的提醒,希望同学们在实操的时候可以一次成功。
大家好,今天为大家介绍Swagger Codegen。Swagger Codegen 相信各位在中大型项目中都使用过,他的功能点和一些自带的特性可以支持绝大数项目的构建,话不多说,咱们直入正题。
什么是 Swagger Codegen 呢?在 Swagger 官网中是这么介绍的:
Swagger Codegen 可以通过为任何 API 生成服务端代码和客户端代码的方式来简化 OpenAPI 的构建过程,因此,项目开发团队可以更好地关注 API 的实现和应用。 —官网
这里提到的 OpenAPI 其实就是我们所谓的 RESTFUL API 规范,关于 RESTFUL API 规范我们已经在 Swagger 简介这一小节中做了详细的介绍,有不清楚的同学可以到该小节了解,这里不再赘述。
通过上面的介绍,说白了,Swagger Codegen 就是一款可以为我们构建服务端代码和客户端代码的工具,也可以把他理解为是一种代码生成框架,而且 Swagger Codegen 用的最多的地方也就是生成服务端和客户端代码。
那么我们为什么要使用 Swagger Codegen 呢?
对于小型项目而言,可能不会用到 Swagger Codegen ,而对于中型及以上规模的项目而言则是很有必要使用的。
我们可以想象这样一种场景:当我们的项目需求确定之后,需要步入到开发阶段时,我们首先做的就是对项目整体进行架构,即我们用什么语言,用什么框架来开发、完成这个项目,这就需要我们首先完成一些架构中的基础设施。
基础设施就是指我们所设计的项目目录、最基本的项目实体类、项目接口类、项目服务类,往往开发这些’基础设施’会耗费我们大量的时间。
所以,当我们在项目中使用了 Swagger Codegen 之后,我们只需要进行一定的配置,运行项目,即可生成我们项目中所需的这些基础设施,这在项目前期为我们节省了大量的时间,使得我们可以把时间用在集中处理项目业务上,提升我们的开发效率。
在我们使用 Swagger Codegen 进行代码生成操作时,我们需要对生成的代码进行统一的规定,在规定完之后,Swagger Codegen 即可为我们生成符合我们要求的代码,而且每一个类都是符合规范的。
这就表明,我们可以在代码生成前灵活的对代码生成规则进行配置,这就使得在最终生成的代码中,我们不用再为代码规范所发愁,不用专门的去修改项目中不符合规范的代码了。
- 学习 Swagger Codegen 这个工具需要大家真实开发过项目,并且使用的是 Java 7 或以上的 JDK 版本。
- 如果你使用过前后端分离的模式构建项目,那么你在学习 Swagger Codegen 时相信会学的很快。

Swagger Codegen 其实就是一款可以为项目生成’基础设施’的代码生成器,包括服务端代码和客户端代码,其强大的生成器和灵活的规则配置可以大大提升在项目前期的编码效率以及项目整体代码的规则约束力,这也是 Swagger Codegen 的核心魅力。
本节会为大家介绍如何在当下主流操作系统中安装 Swagger Codegen 代码生成器。
重点讲解内容:
- 如何在 Windows 系统中安装 Swagger Codegen ;
- 如何在 OS X 系统 (Mac) 中安装 Swagger Codegen ;
- Swagger Codegen 安装是否成功的必要性测试。
针对 Windows 环境,Swagger Codegen 官方并没有直接提供很好的安装方法,所以这里我们采用另一种方式,这也是我总结出来的方法,屡试不爽。
我们进入 Swagger Codegen 的开源界面,会得到官网所推荐的下载 jar 包的链接,链接比较长,这里我已经下好了,同学们可以直接从我的 Git 上进行下载:
https://github.com/SteafanMrZhou/MoocSwaggerWiki
运行以上命令之后,我们会得到很多关于 Swagger Codegen 的帮助信息,如下图所示:

由于我使用的是 Mac 系统,所以我在我的 Mac 上安装了 Win 的虚拟机来为大家演示。
在 OS X 系统中安装 Swagger Codegen 和在 Windows 中安装 Swagger Codegen 大同小异,只是说我们所依赖的平台和安装的方式不同而已,接下来让我们来看看如何在 OS X 系统中安装 Swagger Codegen 吧。
众所周知,如果你是使用 Mac 来工作的,那么你一定听说过 Hoembrew 了,Hoembrew 就类似于我们使用的 Maven ,但是不同于 Maven 的是,他即可以管理项目中的依赖包,也可以管理我们电脑中的依赖包,例如:Java 。
如何确认电脑中是否已经安装了 Homebrew 呢 ? 我们可以在 Mac 的终端中使用以下命令确认:
直接在终端中输入上述命令,然后按回车,如果会提示以下信息,说明 Homebrew 已经安装:

当我们的 Mac 中已经安装了 Hoembrew ,那么我们可以通过以下命令来安装 Swagger-Codegen :

如上图所示,如果你的 Homebrew 已经很长时间没使用了,那么他会自动更新 Homebrew 中已安装的依赖包,这需要等待一段时间。
在更新完 Homebrew 之后,我们可以等待 Swagger-Codegen 的安装完成,如下图所示:

可以看到,当我们输入 help 命令时并不会提示我们像 Windows 环境中的信息,这是因为在 Mac 环境中 Swagger-Codegen 所使用的命令格式和 Windows 中的不一样导致,这里就不再详细介绍了。
当我们运行 jar 包之后出现上述截图中所显示的帮助信息,说明我们下载的 jar 包是正确的,并且也说明 Swagger-Codegen 在我们的电脑中已经安装成功了,接下来就可以使用 Swagger-Codegen 为我们提供的命令来使用 Swagger Codegen 了。
和 Windows 环境一样,如果在 Homebrew 中安装 Swagger-Codegen 结束之后,给我们在终端打印出了 Swagger-Codegen 的帮助提示信息,那就说明我们在 Mac 中使用 Homebrew 安装 Swagger-Codegen 是成功的。
Tips :
- 我们在安装 Swagger-Codegen 的时候,无论是 Windows 平台还是 OS X 平台,首先都需要将 Swagger-Codegen 的 jar 包下载下来,然后我们再针对平台分而治之,但是请记住,无论在哪个平台安装 Swagger-Codegen ,都要确保电脑上是 Java 7 以及更高的版本才行。
- 一般在使用 Swagger-Codegen 的时候,绝大多数情况使用的都是 Swagger-Codegen 的最新稳定版本,所以各位在安装 Swagger-Codegen 时,务必要和本小节中使用的版本 (2.4.14) 保持一致,以免发生不必要的问题。

本小节针对当下主流操作系统,分别详细介绍了在 Windows 平台和 OS X (Mac) 平台安装 Swagger-Codegen 的步骤,以及在安装时候容易出现的问题,针对 Swagger-Codegen 的 Jar 包,考虑到自行下载可能下不动的情况,所以又额外提供了相关资源连接,同学们可以直接下载。

本节会继续结合用户登录接口方法来为大家介绍 Swagger 中的两个关联注解 Authorization 和AuthorizationScope 注解及所提供的常用属性。
Authorization 和AuthorizationScope 注解,在实际项目中很少用到,因为这两个注解是和权限有关的,众所周知,和权限有关的框架或者中间件成熟的已经有很多了,而 Swagger 更多的则是用来生成接口在线文档,重点并不在权限控制上,所以我们只需要掌握他们最基本的用法和常用属性即可。
重点讲解的属性:
- Authorization 注解的 value 、scopes 属性;
- AuthorizationScope 注解的 scope 、 description 属性。
Authorization 注解是作用在接口方法上的注解,用来对该接口方法的访问权限进行控制,即给该接口方法添加的额外权限是什么,一般不会单独使用,经常和 @ApiOperation 注解或者 @Api 注解搭配使用 。
AuthorizationScope 注解也是作用在接口方法上的注解,作用和 @Authorization 注解类似,他是用来描述接口权限的一个范围,即定义该接口的权限范围是什么。
Authorization 和 AuthorizationScope 注解的关系并不像是一组关系紧密的注解,因为 Authorization 注解可以抛开 AuthorizationScope 注解使用。
下面我们来看一下 Authorization 和 AuthorizationScope 两个注解中都包括哪些常用属性。
Authorization 注解
AuthorizationScope 注解
value() 属性
定义:
该属性就是对接口访问权限添加一个名称,即接口访问权限的名称是什么。
使用方法:
value 属性的使用方法有些特殊,不能单独使用,因为单独使用时, Swagger 并不会解析该属性,需要和 @ApiOperaion 注解和 @Api 注解一起搭配使用,这样 Swagger 才会解析该注解。
但是使用该属性所描述的值并不会显示在界面上,只会显示一个标志,表明该接口方法具有 Swagger 的权限控制策略,如果想要在界面上调试该接口需要一定的权限。
这里以 @ApiOperaion 注解为例,在 ApiOperaion 注解中直接声明 authorizations 属性的值即可,authorizations 的值是一个 Authorization 类型的数组。
例如,对于用户登录接口,我想添加一个名称为’普通用户可访问'的权限名称,我们可以这样写:authorizations = { @Authorization(value = “普通用户可访问”) (现在你不需要理解业务代码代表什么意思,重点看所使用的注解及属性即可,下同)。
代码解释:
1-3 行,我们在用户登录接口方法的上方定义了 ApiOperation 注解的 authorizations 属性,其值为 Authorization 注解的 value 属性所描述。
显示结果:

可以看到,在红色箭头所指的右上角位置有一个锁的图片,这个锁的图片就是我们使用 Authorization 注解的 value 属性所展示的效果了。
Tips : 在使用 Authorization 注解的 value 属性前需要在 Swagger 的配置类中取配置和权限有关的 schema ,如果不配置的话,就不能对接口进行权限控制,由于本门课程针对 Swagger 初学者,所以这里就不再介绍了,感兴趣的可以自行查阅资料了解。
scopes() 属性
定义:
该属性就是对接口权限的范围做一个描述,即描述该接口都可以允许哪些权限访问,超过这个权限就不能访问该接口。
使用方法:
scopes 属性的使用方法和 value 属性的使用方法相同,这里还以 @ApiOperation 属性为例,详细代码如下所示。
由于 scopes 属性的值是使用 AuthorizationScope 注解来描述,且 AuthorizationScope 注解的使用要求项目中必须要用到 OAuth2 框架,所以 scopes 属性的描述也要求项目中必须要用到 OAuth2 框架,OAuth2 框架的使用不在本门课程内,所以这里就不再演示了。
综上所述,同学们只需要知道这个属性的基本作用和基本用法即可。
代码解释:
1-3行,我们在用户登录接口方法的上方定义了 ApiOperation 注解的 authorizations 属性,其值为 Authorization 注解的 scopes 属性所描述。
Tips : 在实际项目开发中,如果非要使用 Authorization 注解的 scopes 属性来对接口进行权限控制,那么项目中必须要有 OAuth2 框架,但是往往此框架可以直接对接口进行权限控制,不需要再使用该注解进行配置了。
scope() 和 description() 属性
定义:
scope 属性是用来描述访问接口的权限的具体的一个范围名称,即描述接口访问的单个权限名称。
description 属性就是对这个单个的权限名称做一个简短的描述,来解释说明这个权限所代表的意思。
使用方法:
scope 和 description 两个属性的使用方法和 Authorization 注解中属性的使用方法相同,这里还是以 @ApiOperation 注解为例,详细代码使用方法如下。
代码解释:
我们可以看到,AuthorizationScope 注解中属性的使用方法代码和 Authorization 中的是完全相同的,这就说明:如果想对接口方法定义访问权限范围,则必须要使用 AuthorizationScope 注解才行,这里不再赘述。
Tips :
- 在使用 AuthorizationScope 注解时,注意和 @ApiOperaion 注解的搭配,代码格式稍微有些绕,同学们在学习时需要理清楚代码格式。
- AuthorizationScope 注解的两个属性经常用于在接口权限存在多条时使用,一般很少单独使用。

本小节对 Swagger 中的 Authorization 和 AuthorizationScope 注解及其该注解中的常用属性做了详细介绍,针对两个注解中,经常在实际项目开发中使用的属性,采用图文并茂的方式进行了重点介绍和应用剖析。
无论是 Authorization 注解,还是 AuthorizationScope 注解,都是用来对接口的控制访问权限添加额外的描述,而且 AuthorizationScope 注解中属性的使用还需要项目中必须用到 OAuth2 框架,所以我建议:项目中如果需要对接口添加访问权限控制,那就直接使用权限控制框架就好了。
在学习 Authorization 和 AuthorizationScope 注解及其常用属性时,各位同学注意斟酌这两个注解和权限控制框架之间的差异,要能够做到什么时候使用注解合适,什么时候使用权限控制框架合适。
本节会继续结合一个用户接口相关类来给大家介绍 Swagger 中的另一个注解 SwaggerDefinition 注解及所提供的常用属性。
SwaggerDefinition 注解在实际开发中用的非常少了,尽管他提供了很多属性,但是在绝大多数情况下可以通过配置类解决的问题都不会用 SwaggerDefinition 注解。
所以大家在学习 SwaggerDefinition 注解的时候,只需要掌握基本定义和基本用法即可,由于篇幅有限,我只会选取最重要的属性来给大家截图演示,那些基本不用的就不再截图演示了。
重点讲解的属性:host 、basePath 、tags 、 externalDocs 。
SwaggerDefinition 注解是作用在接口类上面的注解,其主要是用来给 Swagger 生成的 UI 界面(下称 swagger-ui 界面)做一些额外的描述。
SwaggerDefinition 注解提供了丰富的属性来允许我们自定义 swagger-ui 界面的描述信息,包括界面访问地址、界面版本等。
下面我们来看一下 SwaggerDefinition 注解中都有哪些常用的属性。
定义:
host 属性就是描述 swagger-ui 界面的访问主机,或者说是 Ip 地址,即如果,我想访问 Swagger 为我们生成的 swagger-ui 界面,所需要在浏览器地址栏中输入的地址信息。
basePath 属性就是描述 swagger-ui 界面的完整访问地址,他需要依赖 host 属性。
使用方法:
在 SwaggerDefinition 注解中,声明 host 和 basePath属性的值即可。
例如,我想让 swagger-ui 界面在本地就可以访问,那么我们可以这样描述 host 属性:host = “localhost”, 而 basePath 属性可以这样描述:basePath = “localhost:9001”,这样我们就能很清楚的知道 swagger-ui 界面所在的位置了(现在你不需要理解业务代码代表什么意思,重点看接口类上使用的注解及属性即可,下同)。
代码解释:
第 1 行,我们在 UserController 用户接口类的上方,使用了 @SwaggerDefinition 注解的 host 属性和 basePath 属性来规定 swagger-ui 界面的生成位置。
显示结果:

可以看到,在用红框圈起来的地方,就是我们使用 host 属性和 basePath 属性所描述的 swagger-ui 界面的访问路径了。
Tips :
- host 属性和 basePath 属性的区别在于:前者只是定义了 swagger-ui 界面的访问 Ip 地址,如果没有端口的限制,则可以直接访问;而后者则是定义了 swagger-ui 界面的完整位置,其中就包括了端口的存在。
- 在实际开发工作中,往往不需要使用这两个属性来专门的定义 swagger-ui 的访问路径,因为 Swagger 会默认获取项目中通过配置类来定义的地址信息,使用这两个属性就多此一举了。
定义:
该属性就是对项目中所有的接口,添加分组类型描述,即在全局层面定义接口的所属分组类型,类似于 @Api 和 @ApiOperaiton 注解中的 tags 属性。
使用方法:
在 SwaggerDefinition 注解中声明 tags 的值即可,如果没有描述则默认值为空。例如,就用户接口类而言,该接口类属于用户业务分组,所以我们将 tags 的值描述为'用户’或者'user’,这样我们就能很清楚的看到这个接口类是属于用户业务组的,如下代码段所示。
代码解释:
第 1 行,我们在 UserController 接口类的上方使用了 @SwaggerDefinition 注解的 tags 属性来描述该接口类所属的业务分组。
Tips : 该属性在实际工作中基本很少使用,如果有的接口需要进行分组,那么可以直接使用 @Api 注解的 tags 属性来描述,大家只需要知道 SwaggerDefinition 注解存在一个 tags 属性即可。
定义:
如果接口方法或其中的参数存在额外的文档描述,则可以通过该属性进行绑定,即为接口方法或其中的参数提供额外的文档支持。
使用方法:
在 SwaggerDefinition 注解中声明 externalDocs 的值即可。例如,如果我想添加一个额外的文档地址,那么我可以这样写 externalDocs = @ExternalDocs(url = “localhost:8000”),如下代码段所示。
代码解释:
第 1 行,我们在 UserController 接口类的上方使用了 @SwaggerDefinition 注解的 externalDocs 属性来描述额外文档的地址信息。
Tips : externalDocs 属性很少使用,在实际工作中,如果有的接口方法和接口方法中的参数有其他额外的描述话,就直接使用 @ApiOperation 来一并说明了,并不会单独使用一个注解再来说明。

本小节对 Swagger 中的 SwaggerDefinition 注解及其该注解的常用属性做了详细的讲解,针对 SwaggerDefinition 注解中,经常在实际项目开发中使用的属性,采用图文并茂的方式进行了重点介绍和应用剖析,对于一些在实际项目开发中使用基本很少的注解做了概要讲解。
SwaggerDefinition 虽是 Swagger 众多注解中的一个注解,但在实际开发工作中其存在的价值值得我们重新考量。
本节会结合一个用户相关接口类来为大家介绍 Swagger 中的三个小注解 - Info、Contact、License 注解及所提供的常用属性。
Info、Contact、License 这三个注解均不能单独使用,都需要搭配其他注解才能使用,鉴于篇幅有限,所以这里就不再对搭配使用的注解逐一介绍了。
对于这三个小注解,我们只需要了解他们分别代表什么含义,以及他们都有哪些属性,属性的作用都是什么就可以了。
重点讲解的属性:
- Info 注解的 title 、 version 、 description ;
- Contact 注解的 name 、 url 、 email ;
- License 注解的 name 、 url。
Info 、Contact 、License、三个注解都是作用在接口类上的注解,用来对 swagge-ui 界面上的一些信息进行描述,一般都不会单独使用,经常和 @SwaggerDifinitiion 注解搭配使用,他们的不同点在于:
Info 注解是对 swagger-ui 界面上的基本信息进行描述,包括但不限于界面的标题、界面的介绍等。
Contact 注解是对 swagger-ui 界面上的一些和接口有关的联系人的信息进行描述,包括但不限于开发人员名称、地址等。
License 注解是对 swagger-ui 界面上的一些和接口有关的服务条款或者使用的开源协议进行描述,包括服务名称、服务所在地址。
下面我们来看一下上述三个注解中都包括哪些常用属性。
Info 注解
Contact 注解
License 注解
title() 、version() 、 description() 属性
定义:
title() 属性就是对界面的标题做一个描述,即描述界面的标题叫什么。
version() 属性就是对界面的版本做一个描述,通常这个版本指的是接口文档的版本,即描述当前接口文档属于什么版本。
description() 属性就是对界面做一个简单扼要的介绍,即用来描述界面是用来干什么的或者一些其他的注意事项等。
使用方法:
上述三个属性均可以在 Info 注解中注解声明,具体使用方法请看如下代码:(现在你不需要理解业务代码代表什么意思,重点看所使用的注解及属性即可,下同)。
代码解释:
1-3 行,我们在用户相关接口类的上方定义了 Info 注解的 title 、 version 、 description 属性,由于篇幅有限,这里就不截图演示了。
Tips : Info 注解的使用方法我们可以看到是搭配 @SwaggerDefinition 注解的,在实际项目开发中,Info 注解很少使用,所以大家只要了解基本定义和基本用法即可。
name() 、url() 、email() 属性
定义:
name 属性就是用来描述开发或者配置这个界面的开发者或者管理员的名称,一般是指系统开发人员的名称。
url 属性就是对通过 name 属性所描述的人的进一步介绍信息,如果这个人有个人博客或者其他网站介绍的话,都可以通过该属性进行指名。
email 属性就是描述 name 属性所描述的人的邮箱地址,即这个人的邮箱地址是什么。
使用方法:
name 、 url 、 email 属性都可以直接在 Contact 注解中直接声明来使用,具体使用方法请看下述代码:
代码解释:
1-3 行,我们在 SwaggerDefinition 注解的 info 属性中使用了 contact 属性,并将其值描述为 @Contact 注解的相关属性,这就是 @Contact 注解及其属性的使用方法,由于篇幅有限,这里就不截图演示了。
Tips :
- 在实际项目开发功能中,name 属性的值可以是任意名称,只要在有问题时可以查询到这个人是谁就可以了。
- email 属性的值一般都是具体人的真实邮箱了,因为很多公司是通过邮件的方式来进行问题的沟通。
- url 属性的值一般指的就是具体人的个人技术博客,或者自建的个人网站等,通过这种方式可以全方面了解这个人的技术水平。
name() 、url() 属性
定义:
name 属性就是用来描述界面上,具体来讲是系统中所使用的服务条款、开源协议等。
url 属性就是用来描述其服务条款或开源协议所引用的地址信息。
使用方法:
name 、 url 属性都可以直接在 License 注解中直接声明来使用,具体使用方法请看下述代码:
代码解释:
2-4 行,我们在 SwaggerDefinition 注解的 info 属性中,使用了 license 属性,并将其值描述为 @License 注解的相关属性,这就是 @License 注解及其属性的使用方法,由于篇幅有限,这里就不截图演示了。
Tips : 只要项目中存在引用了外部服务条款或者开源协议的情况,无论使用规模多少,都应该用 @License 注解的相关属性表明,以免由于版权问题引起不必要的纠纷。

本小节对 Swagger 中的 Info、Contact、License 三个小注解及其注解中的常用属性做了详细介绍,针对注解中经常在实际项目开发中使用的属性进行了重点介绍和应用剖析。
Info、Contact、License 这三个注解其实并没有太大的作用,因为这三个注解在项目中所起的作用通过一个 Swagger 配置类即可完成,而且配置类在配置起来还相对灵活,所以我建议:如果项目中需要配置 swagger-ui 界面的描述信息,请综合考虑之后再决定是采用配置类的形式还是采用注解的形式。
在学习 Info、Contact、License 注解及其常用属性时,各位同学注意注意区分这三个注解的不同之处,理清在不同场景下应该如何应用这三个注解的关系就可以了。
本节会结合一个用户登录接口方法来为大家介绍 Swagger 中的两个关联注解 - Extension 和 ExtensionProperty 及所提供的常用属性。
Extension 和 ExtensionProperty 不能单独使用,需要搭配 @ApiOperation 注解使用,单独使用没有任何效果。
在实际项目中也是很少用到,其提供的属性也是很少,所以我们只需要掌握他们最基本的用法和常用属性即可。
重点讲解的属性:
- Extension 注解的 name 、 properties ;
- ExtensionProperty 注解的 name 、 value 。
Extension 和 ExtensionProperty 这两个注解属于关联注解,都是用来对接口方法中之外的但是也是和这个方法有关的参数属性进行描述说明,即都是针对接口方法之外但是也和这个方法有关的参数进行补充说明,在 Swagger 中这一类的参数我们称为接口方法拓展参数 (如果对这个概念不理解,请自行查阅)。
下面我们来看一下 Extension 和 ExtensionProperty 两个注解中都包括哪些常用属性。
Extension 注解
ExtensionProperty 注解
name () 和 properties () 属性
定义:
name 属性就是定义拓展参数数组列表的名称,也可以理解为定义拓展参数的名称。
properties 属性就是定义拓展参数的列表,即将拓展参数放到一个数组里面,可以是一个也可以是多个。
使用方法:
name 和 properties 两个属性虽然属于 @Extension 注解,但是 @Extension 注解不能单独拿来使用,需要和 @ApiOperation 注解一起搭配才能使用,因为在 @ApiOperation 注解中存在一个名为 extensions 的属性,其属性的值就是通过 @Extension 注解来描述的。
例如,对于用户登录方法,我想为其添加一个拓展参数,那我们可以这样写:(现在你不需要理解业务代码代表什么意思,重点看所使用的注解及属性即可,下同)。
代码解释:
1-3 行,我们在用户登录接口方法的上方通过使用 @ApiOperation 注解来使用 @Extension 注解的 name 和 properties 属性,由于篇幅有限,这里就不给大家截图演示了。
Tips :
- 在使用 @Extension 注解及其相关属性时,一定要看清楚该注解是通过哪种方法进行使用的。
- 在实际项目开发中,一般具体的一个接口很少会出现拓展参数,如果存在,那也是通过业务需求来描述的,我们不能随意编造任何拓展参数。
name () 和 value () 属性
定义:
name 属性是用来描述接口方法中每一个拓展参数的名称,即给每一个拓展参数都起一个名字。
value 属性表示每一个接口方法中的拓展参数的具体的值,或者对拓展参数的解释说明。
使用方法:
name 和 value 两个属性的使用方法和 @Extension 注解中属性的使用方法相同,这里还是以 @ApiOperation 注解为例,详细代码使用方法如下。
代码解释:
我们可以看到,ExtensionProperty 注解中,属性的使用方法,是通过 @ApiOperation 注解中的 properties 属性来定义的,这里不再赘述。
Tips :
- 在使用 ExtensionProperty 注解时,注意是和 @ApiOperaion 注解中的哪个属性进行搭配,其固定的代码方式是什么,这是同学们需要理清的地方。
- ExtensionProperty 注解的两个属性经常用于指名多个接口方法中的拓展参数,很少会只指名一条,在实际开发中,如果接口方法存在多个拓展参数,那么应该都指名出来才对。

本小节对 Swagger 中的 Extension 和 ExtensionProperty 注解及其该注解中的常用属性做了详细介绍,针对两个注解中经常在实际项目开发中使用的属性进行了重点介绍和应用剖析。
在学习 Extension 和 ExtensionProperty 注解及其常用属性时,各位同学需要注解和其他注解搭配的使用方法,因为这两个注解均不能单独拿出来使用。
写到这里呢,在 Swagger 中的注解及其属性都给大家介绍完毕了,那么我们现在需要掌握的就是在真正的项目中对这些注解进行实操,达到真正会使用的目的。
在前面所讲课程中,课程内容都是针对 Swagger 中的一个注解进行介绍,并不会介绍各个注解间都有一个什么样的关系,以及各个主键间如何搭配或者配合使用。
针对上述问题,本节会结合几个在 Swagger 中使用频率非常高的注解进行组合式讲解,无论是两个注解间的搭配使用,还是多个注解间的配合使用,我都会在本节中进行详细介绍,小伙伴们赶快打击精神来学习吧!
本节会结合以下几个常用注解进行组合实战讲解:
- @Api 注解;
- @ApiOperation 注解;
- @ApiParam 注解;
- @ApiImplicitParams 注解;
- @ApiResponses 注解;
- @ApiModel 注解;
- @ApiModelProperty 注解。
本节主要内容有:
- @Api 注解与 @ApiOperation 注解组合实战;
- @ApiParam 注解与 @ApiImplicitParams 注解组合实战;
- @ApiModel 注解与 @ApiModelProperty 注解组合实战;
- @ApiImplicitParams 注解与 @ApiResponses 注解组合实战。
希望大家在学习本节过程中能够真正掌握多个注解间配合使用的方法,做到融会贯通,随手拈来。
实操目标: 实现接口类与接口类中所有接口方法的准确描述。
实现思路:
第一步:使用 @Api 注解对接口类进行描述。
第二步:使用 @ApiOperation 注解对接口类中所有接口方法进行描述。
第三步:查看配置结果。
实现代码:
接口类:
代码解释:
第 1 行,我们在接口类的上方使用 @Api 注解的 value 属性和 description 属性以及 tags 属性为接口类添加了一些文字描述信息来对接口类进行一些必要的描述。
其中,value 属性表示接口类在 Swagger 界面上所显示的名称,description 表示对接口类的描述,tags 属性则表示对该接口类添加一个分组,表明该接口类是属于哪一组的。
实现代码:
接口方法:
代码解释:
第 1 行,我们在接口方法上使用 @ApiOperation 注解的 name 和 value 属性来对接口方法中的参数进行说明,使用 tags 属性来对该接口方法进行一个分组。
显示结果:

可以看到,在第一个标签的位置,从左到右分别表示对该用户相关接口类的分组名称 user , 以及对该用户接口类的说明:'用户相关接口类’。
在第二个标签位置,表示对用户登录接口方法中的 user 对象类型的参数的说明:'用户登录对象’。
Tips :
- 如果在一个接口类中,我们使用了 @Api 注解的 tags 属性来对该接口分组,那么该接口类中的所有接口都将默认被分到该类中,除非我们使用 @ApiOperation 注解的 tags 属性为接口方法重新指定了另外一个分组。
- 在实际项目开发中,@ApiOperation 注解与 @Api 注解经常这样搭配起来用,可以说,只要使用 Swagger 那么必定会这么用,这种使用方法同学们必须掌握。
- 不同版本的 Swagger 显示可能会有不同,这点请同学们注意。
实操目标: 实现对接口方法中多个参数的准确描述,同时体会 @ApiParam 注解与 @ApiImplicitParams 注解使用时的差异。
实现思路:
第一步:使用 @ApiParam 注解对接口方法中的一个参数进行描述,并查看其描述结果。
第二步:使用 @ApiImplicitParams 注解对接口方法中的多个参数进行描述,并查看其描述结果。
第三步:总结对比两个注解使用时的差异。
实现代码:
@ApiParam 注解作用在接口方法上时:
显示结果:

可以看到,在红色框框起来的位置并没有看到关于 session 参数的说明 (正常的话会在红框中出现对 session 参数的说明)。
- @ApiImplicitParams 注解作用在接口方法上时

可以看到,在用红色框框起来的位置分别显示出了使用 @ApiImplicitParams 注解对参数所描述的信息,并且是多个参数。
Tips :
- 如果你使用的是 Swagger 的低版本且只需要对接口中的一个参数进行描述,则可以使用 @ApiParam 注解;如果你使用的是 Swagger 高版本且需要对多个接口中的参数进行描述,则应该首先考虑使用 @ApiImplicitParams 注解。
- 在实际项目开发中,如果需要对接口中的参数进行描述,那么无论需要描述几个参数,都应该首先考虑使用 @ApiImplicitParams 注解,因为他的兼容性是最好的。
- 在 Swagger 高版本中,@ApiParam 注解并不会有任何效果,而 @ApiImplicitParams 注解则替代了 @ApiParam 注解的作用效果,并且支持对多个参数同时进行描述,这点需要同学们注意。
实操目标: 以用户实体类为例,实现对用户业务实体 (Entity) 的准确描述,以及对实体中各个字段的准确描述,体会 @ApiModel 注解与 @ApiModelProperty 注解作用效果的不同之处。
实现思路:
第一步:使用 @ApiModel 注解对实体类进行描述。
第二步:使用 @ApiModelProperty 注解对实体类中的所有字段参数进行描述。
第三步:查看配置结果,体会两个注解作用效果的不同之处。
实现代码:
实体类:
代码解释:
第 1 行,我们在用户实体类的上方使用 @ApiModel 注解的 value 属性对实体类进行描述:用户实体,存储用户相关字段。
实体类中的字段:
代码解释:
第 1、3、5、7 行,我们使用 @ApiModelProperty 注解的 name 属性、value 属性、required 属性分别定义了字段的名称,内容以及是否必传。
显示结果:

可以看到,在用蓝色框框起来的位置就是我们使用 @ApiModel 对用户实体类所描述的信息,红色框框起来的位置就是使用 @ApiModelProperty 注解对用户实体类中所有的字段所描述的信息。
值得注意的是,在描述字段时,allowEmptyValue 这个属性我们并没有显式的拿来使用,但是 Swagger 还是给我都显示出来了,这是因为 Swagger 默认会将所有字段的 allowEmptyValue 属性置位 false ,表示字段的值可以为空。
Tips : 一定要注意上述两个注解所作用的效果,@ApiModel 是直接作用在实体类上的,@ApiModelProperty 是直接作用在实体类中所有参数上的,两者不要搞混。
实操目标: 以用户登录接口方法为例,实现对该方法中的参数添加描述信息的同时,对接口的返回状态码进行自定义描述。
实现思路:
第一步:使用 @ApiImplicitParams 注解对接口方法中的参数进行描述。
第二步:使用 @ApiResponses 注解对用户登录接口所返回的状态码添加自定义描述信息。
第三步:查看配置结果。
实现代码:
接口中的参数:
代码解释:
这段代码我们在前面已经介绍过了,显示效果请参考上述截图,这里不再赘述。
自定义接口返回状态码:
代码解释:
1-3 行,我们使用 @ApiResponses 注解对用户登录接口的返回状态码添加了多条自定义描述信息。
显示结果:

可以看到,601、602、603 及其右侧所对应的文字描述就是我们使用 @ApiResponses 注解所描述的信息了。
Tips :
- 在实际项目开发中,如果有需要对一个接口的返回状态码添加描述信息,则请在对接口中参数进行描述时一并添加,@ApiImplicitParams 注解和 @ApiResponses 注解经常一起使用。
- @ApiResponses 注解的使用方法同学们一定要注意,他只有一个属性 value ,并没有其它额外的属性,在使用时一定要注意 value 属性所指定的方式。

本小节针对在 Swagger 中经常在项目开发中使用的几个注解做了进一步介绍,针对 Swagger 中不同注解搭配使用以及多注解组合使用的情况采用图文并茂的方式做了详细介绍和应用剖析,旨在帮助同学们在了解各个注解及其属性之后真正的可以将所学应用到真实的实际项目开发中。
因为本小节偏于实战,注重实操,所以各位同学在学习本小节时应该将本节中所涉及的代码跟着手动敲一遍,然后结合自己的项目或者自己创建的 Demo 来进行学习,这是掌握本节内容最快最直接的方式,也是为将来在项目中使用 Swagger 打下一定的基础。
本小节为 "Swagger 注解" 这一章节中的最后一篇文章,在本章中分别对 Swagger 中的注解做了详细介绍和应用剖析,针对在实际项目中使用频率很高的注解做了进一步的组合实操讲解,掌握本章节内容是学好 Swagger 的基础,所以请同学们在充分掌握本章内容之后再继续学习下面的内容。

本节会继续结合一个用户登录接口给大家介绍 Swagger 中的另一个注解 - ApiImplicitParam注解及所提供的常用属性。
ApiImplicitParam 注解经常来配合其他注解一同使用,并不会经常单独拿来使用,所以,对于 ApiImplicitParam 注解,我们只需要了解它的作用和注意事项即可,不必重点掌握。
希望大家在学习本节过程中能够分清主次,有的放矢。
ApiImplicitParam 注解是作用在接口方法上的注解,用来对该接口中的参数进行简短的描述,常常和 ApiParam 注解一起搭配使用。
ApiImplicitParam 注解提供了丰富的属性,来允许我们自定义接口方法中参数的描述信息,包括接口中参数是否必传、参数类型等。
下面我们来看一下 ApiImplicitParam 注解中都包括哪些主要属性。
定义:
该属性就是描述接口中参数的名称。
使用方法:
在 ApiImplicitParam 注解中声明 name 的值即可。例如,对于用户接口,该接口中存在一个用户对象参数 user ,我们只需要将 name 的值写为 'user’ 就好了,即表明该接口中有一个名称为 user 的参数(现在你不需要理解业务代码代表什么意思,重点看接口类上使用的注解及属性即可,下同)。
代码解释:
第1行,我们在用户登录接口方法的上方,定义了 ApiImplicitParam 注解的 name 属性的值,来描述该方法中参数的名称。
显示结果:

可以看到,在使用红色框框起来的地方就是我们使用 name 属性描述的参数名称了。
Tips :
- 在实际开发工作中,name 属性的值通常被描述为接口方法中参数的名称,一般情况不用单独来描述。
- name 属性的使用不是必须的,即每个接口方法中不一定要使用 name 属性,name 属性的适用范围应该根据接口业务要求来定。
定义:
value() 属性就是对接口方法中的参数,进行简单必要的描述,即来描述接口方法中的参数是用来干什么的。
defaultValue() 属性就是定义接口方法中参数的默认值。
使用方法:
对于 value() 属性,在 ApiImplicitParam 注解中声明 value 的值即可,如果没有描述则默认值为空。例如,就用户登录接口而言,其中的 user 参数是用来接收用户的登录数据的,所以我们可以这样写,value = 'user对象,用来接收用户的登录数据’ 如下代码段所示。
代码解释:
第1行,我们在用户登录接口方法的上方,定义了 ApiImplicitParam 注解的 value 属性的值来对该方法中的参数进行解释说明。
显示结果:

我们可以看到在红色框框起来的地方就是我们对接口方法中参数的解释说明。
对于 defaultValue() 属性,该属性值的定义需要根据接口中参数的类型而定,比如该用户登录接口中的参数类型是一个 user 对象,所以我们在描述的时候应该把 defaultValue() 属性的值使用 json 来填充。
defaultValue() 属性的演示我们会在后续章节-注解组合实战中给大家统一演示,希望大家关注。
Tips : 在实际项目开发工作中,value 属性一般是每个接口方法都需要使用,而 value 属性值的定义则是需要做到简单扼要,切合实际,不能随意描述,需要根据具体业务场景来描述。
定义:
该属性就是对接口方法中参数传递的必要性进行约束,就是该接口方法中的参数是不是一定要传递。
使用方法:
在 ApiImplicitParam 注解中声明 required 的值即可,如果没有描述则默认值为 false 。例如,如果我想规定用户登录接口方法中的 user 参数是必须传递的,那么我可以这样写:required = true ,如下代码段所示。
代码解释:
第1行,我们在用户登录接口方法的上方定义了 ApiImplicitParam 注解的 required 属性的值来要求该参数必须传递。
显示结果:

在我用红框圈起来的地方,我们可以看到在 user 的右上角有红色的 required 标识,这就是我们使用 required 规定参数必传的效果了。
Tips :
- required() 属性需要和 name() 属性一起来使用才能起到约束参数是否必传的目的,如果我们不使用 name() 属性,则 Swagger 就不会知道哪个参数需要 required 属性来描述。
- required() 属性的定义请根据业务文档要求来描述,不要随意描述。
以上是对 ApiImpliciParam 注解中,经常使用的四个属性进行的详细介绍,name 、value 、defaultValue 、 required 这四个属性在使用 ApiImpliciParam 注解时经常使用,希望各位可以正确理解各属性所表达的含义,这是用好 ApiImpliciParam 注解的关键。
在详细讲解完 ApiImpliciParam 重要属性之后,下面我将针对在 ApiImpliciParam 注解中,使用频率不是很高,但是有时也会用到的一些属性做概要性讲解,这些属性分别是:paramType 、 dataType 。
定义:
paramType() 属性就是用来描述接口中的参数应该用在哪个地方,常用的位置有:header、query 、path 。
dataType() 属性就是用来描述接口中参数的类型。
使用方法:
如果我们需要描述接口方法参数的使用位置,那么我们可以直接在 ApiImplicitParam 注解中声明 paramType 的值即可。
dataType() 属性的默认值为 String 字符串类型,如果我们部队参数进行描述,则 Swagger 默认会使用该类型,如果需要明确定义接口中参数的类型,那就在 ApiImplicitParam 注解中声明 dataType 的值即可。
上述两种情况如下代码段所示:
代码解释:
第1行,我们在用户登录接口方法的上方定义了 ApiImplicitParam 注解的 paramType 属性和 dataType 属性来对接口方法中参数的使用位置和类型进行了描述。
由于篇幅限制,该部分注解的演示请参考注解组合实战章节。
Tips : 在实际工作中,paramType 一般不常用,而 dataType 往往每个接口方法都需要使用。
以上则是 ApiImpliciParam 注解中的辅助使用属性的概要介绍,对于剩下的其他属性,在实际项目开发中几乎很少使用,在这里就不再介绍了,如果大家感兴趣,可以去 Swagger 的官网查询相关资料来了解。

本小节对 Swagger 中的 ApiImpliciParam 注解及其该注解的做了详细的讲解,针对 ApiImpliciParam 注解中经常在实际项目开发中使用的属性采用图文并茂的方式进行了重点介绍和应用剖析,对于一些在实际项目开发中使用基本很少的注解做了概要讲解。
在学习 @ApiImpliciParam 注解及其属性时,各位同学应该对比 @ApiParam 注解及其属性之间的使用差异,通过差异比较总结出适合自己的使用规律和使用方法才是最重要的。
本节会结合一个用户操作相关的实体类,来给大家介绍 Swagger 中的两个关联注解 - ApiModel 注解和 ApiModelProperty 注解及所提供的常用属性,使用率较低或基本不适用的注解属性就不再介绍了。
ApiModel 注解和 ApiModelProperty 注解,在实际项目中的使用频率较前面所介绍的注解而言相对较低,我们只需要了解它的作用和注意事项即可,不必重点掌握。
重点讲解的属性:
- ApiModel 注解的 value 、 description 属性;
- ApiModelProperty 注解的 value 、required 、hidden 、 allowEmptyValue 属性。
ApiModel 注解是作用在接口相关实体类上的注解,用来对该接口相关实体类添加额外的描述信息,常常和 @ApiModelProperty 注解配合使用。
ApiModelProperty 注解是作用在接口相关实体类的参数上的注解,用来对具体的接口相关实体类中的参数添加额外的描述信息,常常和 @ApiModel 注解关联使用,有时也会单独拿出来用。
ApiModel 和 ApiModelProperty 两个注解的作用域不同,但是都提供了丰富的属性来允许我们对接口相关实体类和其中的参数添加额外的描述信息。
下面我们来看一下 ApiModel 和 ApiModelProperty 两个注解中都包括哪些主要属性。
ApiModel 注解
ApiModelProperty 注解
value() 属性
定义:
该属性就是对所需要特别说明的接口相关实体类进行描述。
使用方法:
在 ApiModel 注解中不使用 value 属性时,则其默认值为实体类的名称,如果我们想对一个实体类添加特定的描述信息,例如,对于用户实体,我们可以这样写:(现在你不需要理解业务代码代表什么意思,重点看实体类上使用的注解及属性即可,下同)。
代码解释:
第1行,我们在用户实体类的上方定义了 ApiModel 注解的 value 属性的值,来对用户实体添加特定的描述信息。
显示结果:

可以看到,在之前显示 User 的位置,显示了我们使用 ApiModel 注解的 value 属性所描述的信息了。
Tips : 在实际开发工作中,value 属性一般很少使用,只用默认的类型即可,如果有特别不直观的类名,则会考虑使用该注解的 value 属性。
description() 属性
定义:
description 属性就是对所需要特别说明的接口相关实体类进行较长的描述。
使用方法:
在 ApiModel 注解中直接声明 description 属性的值即可,例如,我想对用户实体添加必要的描述信息,则可以这样写:。
代码解释:
第1行,我们在用户实体类的上方定义了 ApiModel 注解的 description 属性的值来对用户实体添加额外的描述信息。
显示结果:

可以看到,在用红框圈起来的地方就是我们使用 description 属性来描述的信息了,值得注意的是,这里的显示样式是 Swagger 默认的,一般不需要修改。
Tips :
- 在实际开发工作中,description 属性一般会配合 value 属性进行使用,很少会出现只是用 value 属性而不使用 description 属性的情况。
- description 属性使用频率同 value 属性。
value() 属性
定义:
该属性就是对实体类中的参数进行一个描述,即该属性用来对实体类中的字段做一个补充说明,来说明该字段代表什么意思。
使用方法:
在 ApiModelProperty 注解中直接声明 value 属性的值即可,例如,在用户实体类中有一个"Id"字段,我想对该字段添加描述信息,则可以这样写:。(现在你不需要理解业务代码代表什么意思,重点看使用的注解及属性即可,下同)。
代码解释:
第1行,我们在 id 字段的上方定义了 ApiModelProperty 注解的 value 属性的值来对 id 字段补充说明。
显示结果:

可以看到,在用红框圈起来的地方就是我们使用 value 属性来描述的信息了。
Tips : 在实际开发工作中,value 属性相对而言还是很常用的,value 属性的定义应该言简意赅,描述的时候不能太啰嗦。
required()、hidden() 属性
定义:
required 属性就是用来描述实体中的参数字段是否必传。
hidden 属性就是用来描述实体中参数字段是否显示在 Swagger 界面中。
使用方法:
在 ApiModelProperty 注解中直接声明 required 属性的值即可,例如,在用户实体类中有一个"Id"字段,我想声明该字段是必传的,则可以这样写:, 。
对于 hidden 属性而言,比如我想将用户的手机号字段不显示,那可以这样写。
代码解释:
第1行,我们在 id 字段的上方定义了 ApiModelProperty 注解的 required 属性的值为 true ,代表该字段必传。
第3行,我们在 phone 字段的上方定义了 ApiModelProperty 注解的 hidden 属性为 true , 代表该字段不在 Swagger 界面上显示。
显示结果:

可以看到,id 字段的后面有一个红色的星号,这表明该字段必传,这就是 required 属性所起的作用。
在整个实体字段中并不能看到 phone 字段,这就是我们使用 hidden 属性所起的作用,我们可以对比上述 value 属性的结果图来看。
Tips :
- 在实际开发工作中,hidden 属性不能滥用,如果哪些字段需要隐藏,请向项目经理提出申请。
- required 属性相对而言还是经常使用的,required 属性的定义应当根据具体的业务需求,不要随意定义,这会引起不必要的麻烦。
allowEmptyValue() 属性
定义:
allowEmptyValue 属性是用来描述实体参数的值是否可以为空。
使用方法:
在 ApiModelProperty 注解中直接声明 allowEmptyValue 属性的值即可,如果我们不声明该属性,则默认为 false,即字段参数的值不可以为空。
如果我们想对 phone 字段声明其值可以为空,则可以这样写:。
代码解释:
第1行,我们在 phone 字段的上方定义了 ApiModelProperty 注解的 allowEmptyValue 属性的值为 true ,代表该字段的值可以为空,在参数传递时可以不填充值。
显示结果:

可以看到,在序号为 1 的标签红框中的 id 字段上,我们并没有定义 allowEmptyValue 属性,所以他默认将该属性描述为了 false , 即 id 参数的值在传递时不可以为空,必须为其填写数据。
在序号为 2 标签红框中的 phone 字段上,我们定义了 allowEmptyValue 属性的值为 true ,即 phone 参数的值在传递时可以为空,这就是 allowEmptyValue 属性所起的作用。
Tips : 在实际开发工作中,allowEmptyValue 属性经常和 required 属性一起搭配使用,但是同样不能滥用,如果哪些字段的值需要在传递时为空,请向项目经理提出申请。

本小节对 Swagger 中的 ApiModel 和 ApiModelProperty 注解及其该注解做了详细讲解,针对两个注解中,经常在实际项目开发中使用的属性,采用图文并茂的方式,进行了重点介绍和应用剖析,由于不同注解的很多属性用法相同,这里就不再赘述了。
在学习 ApiModel 和 ApiModelProperty 注解及其常用属性时,各位同学应该在清楚,什么是实体类的基础上进行学习,因为这两个注解都是针对实体类而言的,其他地方无法使用。
本节会继续结合用户登录接口方法来为大家介绍 Swagger 中的两个关联注解 - ApiResponse 和 ApiResponses 注解及所提供的常用属性,使用率较低或基本不适用的注解属性就不再介绍了。
ApiResponse 和 ApiResponses 注解在实际项目中的使用频率较前面所介绍的注解而言相对较低,我们只需要掌握他们最的基本用法和常用属性即可。
重点讲解的属性:
- ApiResponse 注解的 code 、message 、responseHeaders 属性;
- ApiResponses 注解的 value 属性。
ApiResponse 注解是作用在接口方法上的注解,用来对该接口方法的一个或多个返回值进行描述,一般不会单独使用,常常和 @ApiResponses 注解配合使用。
ApiResponses 注解也是作用在接口方法上的注解,作用和 @ApiResponse 注解相同,只是在当有多个 @ApiResponse 注解同时存在时才会使用该注解。
ApiResponse 和 ApiResponses 注解是一组关系紧密的注解,主要使用的属性都在 @ApiResponse 注解中。
下面我们来看一下 ApiResponse 和 ApiResponses 两个注解中都包括哪些常用属性。
ApiResponse 注解
ApiResponses 注解
code () 和 message () 属性
定义:
code 属性就是描述接口返回的响应数据的状态码。
message 属性就是对接口返回的响应数据的状态码进行描述。
使用方法:
在 ApiResponse 注解中直接声明 code 属性和 message 属性的值即可,例如,对于用户登录接口,我想添加一个值为 666 的状态码,其描述为 success ,代表当接口返回的状态码为 666 时表示请求是成功(success)的。
鉴于上述业务场景,我们可以这样写:code = 666, message = “success”(现在你不需要理解业务代码代表什么意思,重点看实体类上使用的注解及属性即可,下同 。
代码解释:
第 1 行,我们在用户登录接口方法的上方定义了 ApiResponse 注解的 code 属性的值为 666,message 属性的值为 success 来对用户登录接口添加特定的返回信息。
显示结果:

可以看到,在用红框框起来的地方就是我们使用 code 属性和 message 属性所展示的效果了。
Tips :
- 一般而言,在实际项目开发中,http 协议自带的返回状态码已经够用了,不需要开发者再特殊指定,如果业务要求必须遵照一定的规则,那就只能额外规定了。
responseHeaders () 属性
定义:
该属性就是对接口的返回头做一个描述,即犹如请求接口时所规定的请求头为 'application/json’ 类型那样。
使用方法:
在 ApiResponse 注解中,直接声明 responseHeaders 属性的值即可,例如,我想把用户登录接口的返回头类型定义为'multipart/file’ (这样定义显然是不合理的,这里只做演示) ,则可以这样写:description = “用户实体中包含用户相关的所有业务字段,如有需要请另行添加” 。
代码解释:
第 1 行,我们在用户实体类的上方定义了 responseHeaders 属性的值来对用户登录接口的返回头类型添加额外的描述信息。由于篇幅原因这里就不给大家截图了。
Tips :
- responseHeaders 属性值的定义应该按照 http 协议规定好的类别进行描述,如果我们所描述的不是 http 协议所规定的类型,那么在 Swagger 界面上是不会显示出来的,这点需要注意。
- responseHeaders 属性虽然是 ApiResponse 注解中的,但是使用该属性需要以数组的形式使用,即如上述代码示例,因为该注解源码中就是这样定义的。
value () 属性
定义:
ApiResponses 注解的 value 属性就是对接口的返回状态码及其返回状态码描述进行多条描述,来说明该接口的返回格式有多条额外的描述。
使用方法:
ApiResponses 注解规定其 value 属性的类型为 ApiResponse 数组类型,这就说明 value 属性只能使用 @ApiResponse 注解的形式进行描述,同时允许描述多条。
例如,在用户登录接口中,我想对该接口的返回格式添加两条额外描述信息,使用方法如下所示。
代码解释:
1-3 行,我们在用户登录接口方法的上方定义了 ApiResponses 注解的 value 属性来对该接口的返回格式添加两条额外描述信息。
显示结果:

可以看到,600 和 666 及其 error 和 success 就是我们使用 value 属性来对该接口的返回格式添加的额外描述信息了。
Tips :
- 在实际开发工作中,value 属性经常被用来描述一个接口方法的多条返回格式,其内容应该根据业务文档所规定的要求进行描述。
- value 属性内容的填充形式就如上述代码所示,其中 value 这个单词可以不显式的写出来,Swagger 会默认隐藏。
- ApiResponses 注解不能单独使用,因为他只有一个类型为 ApiResponse 数组形式的 value 属性,即要使用 ApiResponses 注解就必须要填充 value 属性。

本小节对 Swagger 中的 ApiResponse 和 ApiResponses 注解,及其该注解中的常用属性,做了详细介绍,针对两个注解中,经常在实际项目开发中使用的属性,采用图文并茂的方式进行了重点介绍和应用剖析。
Tips : 值得注意的是 @ApiResponse 注解一般不可以单独拿来使用,需要搭配 @ApiResponses 注解一起来使用,这样才能在 Swagger-ui 界面看到使用效果。
在学习 ApiResponse 和 ApiResponses 注解及其常用属性时,各位同学应该在清楚常见的 http 状态码及其描述都有哪些以及什么是接口的请求头、响应头的基础上进行学习,因为这两个注解都是针对接口的返回数据及其格式而言的,其他地方无法使用。

本节会继续结合一个用户登录接口给大家介绍 Swagger 中的另一个核心注解 - Api注解及所提供的常用属性。
Api 注解和 ApiOperation 注解一样,在 Swagger 中都扮演着非常重要的角色,Api 注解一般都会配合 ApiOperation 注解一起来使用。
希望大家在学习本节过程中能够分清主次,有的放矢。
Api 注解是作用在接口类上面的注解,其主要是用来给接口类定义相关说明。
Api 注解提供了丰富的属性,来允许我们自定义接口类的描述信息,包括对接口类的简单描述,接口类所属的分组等。
下面我们来看一下 Api 注解中都包括哪些主要属性。
定义:
该属性就是描述接口类的作用是什么,即同一类下的接口都是用来干什么的。
使用方法:
在 Api 注解中声明 value 的值即可。例如,对于用户接口类(UserController),我们只需要将 value 的值写为 'user-controller’就好了,这样我们就能很清楚的知道这个接口类下的所有接口都是用来处理和用户相关的请求的,如下代码段所示(现在你不需要理解业务代码代表什么意思,重点看接口类上使用的注解及属性即可,下同)。
代码解释:
第1行,我们在 UserController 用户接口类的上方使用了 @Api 注解的 value 属性来描述该接口类的作用。
显示结果:

可以看到,在 Created by Steafan 下放黑体加粗显示的 user-Controller 就是我们使用 value 属性描述的接口类信息了。
Tips :
- 通过 value 属性来对接口类进行描述的这一行为在实际开发工作中并不常用,各位同学只需要知道有这么一个 value 属性就可以了。
- 在实际开发工作中, value 属性经常被 tags 属性所替代,这也是 Swagger 官方所设定的规则:当 Api 注解的 value 属性和 tags 属性同时存在时,tags 属性的值会替代 value 属性的值,这一点需要同学们注意。
定义:
该属性就是对实现相同业务功能的接口类做一个大型的分组,该分组中包括同业务功能下的所有的接口。
使用方法:
在 Api 注解中声明 tags 的值即可,如果没有描述则默认值为空。例如,就用户接口类而言,该接口类属于用户业务分组,所以我们将 tags 的值描述为'用户’或者'user’,这样我们就能很清楚的看到这个接口类是属于用户业务组的,如下代码段所示。
代码解释:
第1行,我们在 UserController 接口类的上方使用了 @Api 注解的 tags 属性来描述该接口类所属的业务分组。
显示结果:

我们可以看到在 value 属性的值的位置显示了 user ,也就是 tags 里写的 user 了。
上述是 tags 属性和 value 属性单独存在时候的效果,下面我们来看一下 tags 属性和 value 属性同时存在的效果,如下代码段所示:
代码解释:
第1行,我们在 UserController 接口类的上方使用了 @Api 注解的 value 属性和 tags 属性同时来描述该接口类。
显示结果:

我们可以看到显示结果是和只使用 tags 属性来描述接口类时相同的结果,这也证明了 Swagger 官方的设定。
Tips : 在实际项目开发工作中,往往一个业务可能包括多个接口类的实现,这种情况需要我们对接口类进行多个分组,而 tags 属性的类型是字符串类型的数组,可以描述一个或多个值,如存在多值时,应该使用这种方式来描述:@Api(tags = {“user”, “customer”})。
定义:
该属性就是对接口类进行简单概要的描述,通常是描述一些注意的地方,value 属性更多的则是描述接口类的用途,这一点同学们要分清。
使用方法:
在 Api 注解中声明 description 的值即可,如果没有描述则默认值为空。例如,如果我想添加对用户接口类的概要描述信息,那么我可以这样写 description = “所有用户业务接口必须使用post请求”,如下代码段所示。
代码解释:
第1行,我们在 UserController 接口类的上方使用了 @Api 注解的 description 属性来描述用户接口类的一些注意的地方和约定。
显示结果:

在我用红框圈起来的地方我们可以看到使用 description 注解所描述的信息了。
Tips :
- description 属性一般用来对接口类进行一些注意事项和约定的描述,不要将其描述为接口类的用途。
- description 属性在实际开发工作中还是很常用的,所以描述好 description 是体现一个程序员对业务内容是否充分理解的标志。
以上是对 Api 注解中经常使用的三个属性进行的详细介绍,value,tags,description 这三个属性不管是在项目开发中,还是在需求沟通中,使用的都很频繁,所以真正掌握这三个属性,是用好 Api 注解的重要前提。在学习这三个属性时,大家应该结合 ApiOperation 注解来对比并总结它们之间的差异,通过不断的使用来发现它们的使用规律,这一点很重要。
在详细讲解完 Api 重要属性之后,下面我将针对在 Api 注解中,使用频率不是很高,但是有时也会用到的一些属性做概要性讲解,这些属性分别是:consumes、produces、protocols、hidden。
定义:
protocols() 属性就是对接口类中,所有的接口所使用的网络协议进行一个约定,常用的网络协议有:http、https。
hidden() 属性就是控制接口类在 Swagger 界面中的显隐性。
使用方法:
protocols() 属性默认值为空,但是 Swagger 在处理时,会默认获取项目所采用的网络协议,我们可以不用专门设置,如果一定要设置该属性,则只允许设置http协议规定的属性,不能随意设置,http, https 这些都是被允许的。
hidden() 属性允许我们在 Swagger 生成的接口列表界面上,控制接口类是否需要显示,默认值为 false,即接口类显示,为true时则接口类不显示,如下代码段所示。
代码解释:
第1行,我们在 UserController 接口类的上方使用了 @Api 注解的 hidden 属性来隐藏我们的用户接口类。
Tips :
- 接口类的显隐控制应该根据特定安全策略和特定客户需求来决定显隐,不能无故隐藏接口,更不能频繁的切换接口的显隐。
- 在实际工作中,如果需要隐藏接口类则需要和项目组报备情况,说明原因。
以上则是 Api 注解中的辅助使用属性的概要介绍,对于剩下的 produces、consumes 属性在实际项目开发中几乎很少使用,在这里就不再介绍了,如果大家感兴趣可以去 Swagger 的官网查询相关资料来了解。

本小节对 Swagger 中另一个最经常使用的 Api 注解及其该注解的各个属性做了详细的讲解,针对 Api 注解中经常在实际项目开发中使用的属性采用图文并茂的方式进行了重点介绍和应用剖析,对于一些在实际项目开发中使用基本很少的注解做了概要讲解。
在学习 @Api 注解及其属性时,各位同学应该对比 @ApiOperation 注解及其属性之间的使用差异,通过差异比较总结出适合自己的使用规律和使用方法才是最重要的。
本节会继续结合一个用户登录接口给大家介绍 Swagger 中的另一个核心注解 - ApiParam 注解及所提供的常用属性。
ApiParam 注解一般会结合 ApiOperation 注解以及 Api 注解一起来使用。
希望大家在学习本节过程中能够分清主次,有的放矢。
ApiParam 注解,是可以作用在接口方法上面,以及接口方法中的参数位置的注解,其主要是用来给接口中的参数定义相关参数说明,主要是为了,帮助相关人员理解接口中每个参数的含义。
ApiParam 注解同样也提供了丰富的属性,来允许我们对接口中的参数添加描述信息,包括该参数的具体含义、参数是否必须传递等。
下面我们来看一下 ApiParam 注解中都包括哪些主要属性。
定义:
该属性就是描述接口中参数的名称。
使用方法:
在 ApiParam 注解中声明 name 的值即可。例如,对于用户接口而言,在本例中,需要传递的参数是一个 user 对象,所以我们需要将 name 的值写为 'user’就可以了,这样,我们就能很清楚的知道,这个接口方法中传递的参数是一个 user 对象了,如下代码段所示(现在你不需要理解业务代码代表什么意思,重点看接口方法上使用的注解及属性即可,下同)。
代码解释:
第1行,我们在 login 接口方法的上方使用了 @ApiParam 注解的 name 属性来描述该接口中的参数名称。
显示结果:

可以看到,在 Parameters 内容区中用红框圈起来的 Parameter 参数的名称就是我们使用 name 属性来描述的接口参数名称。
Tips :
- 在实际开发工作中,name 属性的值一般都是根据接口方法中的形参来描述,即接口方法中默认声明的参数名称,除非有特殊说明才可以描述与形参名称不同的值。
- 如果我们没有使用 name 属性来描述参数的名称,则参数名称默认为接口中自带的参数名称。
定义:
该属性就是对接口中的参数做一个简要的描述,即来说明接口中的参数是用来做什么的。
使用方法:
在 ApiParam 注解中声明 value 的值即可,如果没有描述则默认值为空。例如,就用户接口而言,该接口中的参数是一个用户对象,则我们可以在 value 属性中添加这样的描述:'用户对象,用于用户登录检测,必传’,如下代码段所示。
代码解释:
第1行,我们在 login 方法的上方使用了 @ApiParam 注解的 name 属性和 value 属性来对接口方法中的 user 参数做一个简单必要的说明。
显示结果:

我们可以看到在 Parameters 内容区域的 Description 红框圈起来的地方并没有显示出我们使用 value 属性所描述的信息,从某种意义上(Swagger 源码角度)讲,这是 Swagger-UI 的一个 Bug ,但是从使用角度来讲可能就是我们用错了 @ApiParam 注解。
如果我们想在 Description 中显示我们所描述的信息,我们又该怎么做呢?
在本节的开篇中,就已经说明了 @ApiParame 既可以写在接口方法的上方,也可以写在接口中参数的位置,在上图中我们是把注解写在了接口方法的上方,那么现在我们来看一下,将注解写在接口中参数的位置时又是一种什么效果吧:
代码解释:
第1行,我们修改了 @ApiParam 注解的位置,把注解写到了和接口参数相同的位置,通过这种方式来对 user 参数做一个简单必要的说明。
显示结果:

我们可以看到,在 Parameters 内容区域的 Description 位置,已经显示出了我们使用 value 来对 user 参数所描述的信息,上述两种使用 value 的情况请同学们特别注意。
Tips :
- value 属性用于描述接口中字段的说明,一般是一些必要的重要信息,不要描述很长的一段话,如果是一般简单性的描述,那还是不要写出来为好。
- 出于国人习惯的考虑,在描述 value 属性的值时,尽量使用中文来描述,这样可以做到显而易见、通俗易懂。
- 鉴于 value 属性的特殊情况,同学们在使用时应该注意:如果接口的方法参数就一个且该参数很好理解,这种情况就在接口方法的上面描述;如果接口的方法参数不便于理解,这种情况就要在接口的方法位置来描述,请同学们根据情况合理使用。
定义:
该属性就是对接口方法中的参数默认值进行描述,即对接口中存在默认值的参数进行简单的描述。
使用方法:
在 ApiParam 注解中,声明 defaultValue 的值即可,如果没有描述则默认值为空。例如,如果我想对用户接口方法中的 user 对象参数中的一个属性,添加默认值描述,那么我可以这样写 defaultValue = “ admin ”(严格来讲,user 参数的默认值应该是一个 json 串,这里为了演示就简单描述了),如下代码段所示。
代码解释:
第1行,我们在 login 接口方法的上方使用了 @ApiParam 注解的 defaultValue 属性来对用户登录接口中存在默认值的属性进行描述。
defaultValue 属性并没有直接的界面显示效果,这个作用效果可以在使用 swagger-ui 进行接口调试的时候可以很直观的看到。
当我们在传递某一参数时,如果我们没有给该参数填充数据,同时该参数被 defaultValue 属性所描述,此时该参数的数据就会变为 defaultValue 属性所描述的值了。这一点在如何使用 swagger-ui 进行接口调试小节中会详细介绍。
Tips :
- defaultValue 属性不要滥用,其用于对接口方法中存在默认值的参数进行说明,如果在接口方法中不存在有默认值的参数,那就不要使用该属性。
- 如果一个接口方法中存在多个有默认值的参数需要说明,那么请使用 @ApiParam 注解的 defaultValue 属性来对参数分别进行说明。
定义:
该属性就是对接口方法中参数传递的必要性做一个约定,即接口方法中的参数哪些是必须传递的,哪些是非必须传递的。
使用方法:
在 ApiParam 注解中,声明 required 的值即可,如果没有描述则默认值为 false , 即参数为非必须传递。例如,如果我想把用户登录接口方法中的参数描述为必须传递,那么我可以这样写 required = true,如下代码段所示。
代码解释:
第1行,我们在 login 接口方法的上方使用了 @ApiParam 注解的 required 属性来将用户登录接口中的属性描述为必须传递。
如果想要看到 required 属性的作用效果,就需要我们改变浏览器地址栏的路径了:在浏览器地址栏中输入:swagger-ui 访问路径 + /v2/api-docs(至于为什么是这个路径,在后面的文章中会详细说明),在输入完上述 url 之后我们会看到一个由多个 json 串所组成的界面,而这些 json 串的内容正是我们所写的接口。
显示结果:

可以看到,我在用户登录接口的 json 串中用红框圈起来的就是我们使用 required 所描述的结果了。
定义:
该属性就是对接口方法中的参数的可取值范围进行描述。
使用方法:
在 ApiParam 注解中,声明 allowableValues 的值即可,如果没有描述则默认值为空,值得注意的是,使用该属性需要遵循特性的描述格式。例如,如果我想把用户登录接口方法中的参数描述为必须传递,那么我可以这样写 required = true,如下代码段所示。
代码解释:
第1行,我们在 getUserInfo 接口方法的上方使用了 @ApiParam 注解的 allowableValues 属性来对用户 id 值的可取范围做一个限制。
当我们以上述接口方法的形式来使用 allowableValues 属性时并不能在 swagger-ui 界面看到任何效果,这应该是 swagger-ui 的一个 bug ,至于使用效果如何,请看后面使用 swagger-ui 进行接口调试小节的内容。
Tips : 在实际项目开发工作中,allowableValues 使用的频率并不是很高,一般都是为了避免参数传递不合法才设置该属性。
以上是对 ApiParam 注解中经常使用的五个属性进行的详细介绍,name , values , defatluValue , required , allowableValues 掌握这五个属性的使用搭配习惯是真正用好 ApiParam 注解的重要前提。在学习这五个属性时,大家应该结合 ApiOperation 注解来对比并总结它们之间的差异,通过不断的使用来发现它们的使用规律,这一点很重要。
在详细讲解完 ApiParam 重要属性之后,下面我将针对,在 ApiParam 注解中使用频率不是很高,但是有时也会用到的一些属性做概要性讲解,这些属性分别是:access、allowMultiple、example、hidden 。
定义:
example() 属性就是描述接口方法中的一个参数的示例值。
hidden() 属性就是控制接口方法中的参数在 Swagger 界面中的显隐性。
使用方法:
example() 属性默认值为空,当我们需要对接口中的方法添加示例值描述时,可以使用该属性进行描述。例如,对于获取用户信息方法而言,需要传递的参数为用户的 id ,则我可以描述一个示例值为 1。
hidden() 属性允许我们在 Swagger 生成的接口列表界面上,控制接口方法中的参数是否需要显示,默认值为 false,即接口方法中的参数显示,为true时则接口方法中的参数不显示,如下代码段所示。
代码解释:
第1行,我们在 getUserInfo 接口方法中对 userId 参数通过 example 属性描述了示例值,对 username 进行了隐藏。
Tips :
- 接口方法中参数的显隐控制应该根据特定安全策略和特定客户需求来决定显隐,不能无故隐藏接口参数,更不能频繁的切换接口参数的显隐。
- 在实际工作中,应该根据业务要求来合理描述接口中参数的示例值,不能随便描述,更不能描述不清楚。
以上则是 ApiParam 注解中的辅助使用属性的概要介绍,对于剩下的 access、allowMultiple 属性在实际项目开发中几乎很少使用,在这里就不再介绍了,如果大家感兴趣可以去 Swagger 的官网查询相关资料来了解。

本小节对 Swagger 中另一个最经常使用的 ApiParam 注解及其该注解的各个属性做了详细的讲解,针对 ApiParam 注解中经常在实际项目开发中使用的属性采用图文并茂的方式进行了重点介绍和应用剖析,对于一些在实际项目开发中使用基本很少的注解做了概要讲解。
在学习 @ApiParam 注解及其属性时,各位同学应该对比 @ApiOperation 注解及其属性之间的使用差异,通过差异比较总结出适合自己的使用规律和使用方法才是最重要的。


大家好,今天我们开始一个新专题 — Swagger。
关于 Swagger 相信我们都在实际项目开发中使用过,它的核心知识点完全可以整理成一组专题来展开介绍,本专题我们重点讲解 Swagger 在基于 Java 生态框架的日常开发过中如何来应用。
本文我们主要先介绍一下 Swagger 是什么?有哪些特性?优缺点在哪?为什么我们需要在项目开发中应用 Swagger ?
什么是 Swagger 呢?在 Swagger 官网中是这么介绍的:
Swagger 就是一种可以帮助我们简化 API 开发过程的工具。 — 官网
我们看到,这里提到了 API 这一术语,在业界,API 一般指的是:通过后端编码而开发出来的,且可以供其他用户所使用的一种专门对外暴露的数据传输接口,即我们可以通过编写 API 来达到和用户交互的目的。俗话说无规矩不成方圆,针对 API 业界也制定了一款标准,那就是 RESTFUL API 规范,下面我们来简单介绍一下什么是 RESTFUL API 规范:
的全称是 Representational State Transfer,即表述性状态转换,或者我们可以通俗的理解为:一组具有约束条件和原则的规范。
也就是说:RESTFUL API 就是经过一组确定好的具有约束行为和统一原则的规范来规定 API 书写规则、命名规则、请求规则、响应规则的一种表述性方式。通过这个方式我们可以很好地理解具体 API 所代表的的业务场景和返回字段的含义。
通过上面的介绍,说白了,Swagger 就是一款可以简化项目 API 开发的工具,用来帮助我们通过最简单的途径来开发 RESTFUL API。
那么我们为什么要使用 Swagger 呢?
如果我们需要在项目中使用 Swagger,那么我们只需要将 Swagger 的依赖集成到项目中去,然后通过一个简单的 Swagger 配置类即可开始使用了,不需要像其他工具那样还要繁琐的去配置 xml,即配置简单,容易上手。这为我们节省了大量的时间,使得我们可以把时间用在集中处理项目业务上,提升我们的开发效率。
Swagger 通过内置 html 解析器的方式来实现将 RESTFUL API 显示在界面上供开发者查看,Swagger 提供的界面样式即简洁又美观,开发者可以很直观地看到自己所编写的 RESTFUL API 的请求方式、请求参数、返回格式以及所属业务组,如下图所示。

我们在开发 Java 项目的时候,主要的目的就是对外暴露我们的数据传输接口,来实现前后台数据交互的目的。
针对于我们编写的接口,往往我们需要撰写接口文档来说明具体接口所做的业务是什么,以及这个接口如何使用。这样在无形之中就加重了我们的工作内容,而有了 Swagger 之后,我们只需要在相应的地方添加 Swagger 的注解来对接口进行简单的说明,它就会帮助我们生成一份完整的接口说明,见上图。
这样一来我们就不用再编写一份几十页甚至几百页的接口文档了,提升了交互性能,同时也提升了前后台开发者的沟通效率。
总结:
Swagger 它是一个帮助开发人员来简化开发 RESTFUL API 的一款开发工具,其核心是基于 NPM 实现,在 Spring 项目中则是通过封装 SpringFox 依赖来完成对接口请求方式、请求参数、响应数据的加载,最终通过前端界面的方式来展现给用户。Swagger 具有简单、方便、高效的特性,用 Swagger 构建 RESTFUL API 可快速又方便。
Swagger 从 2011 年发布至今已经有 9 个年头,期间已经迭代升级了很多版本,现在最新的版本是 v3.18.3,每个版本都有不同的特性,下面主要介绍一个主要使用的版本和新版本的特性。
- V1.0.1 - 1.0.13: 最初发布版本,基本已经很少使用了。
- V2.X.X: 目前使用较多的版本,也是我们这个课程使用的版本。
- V3.18.3: 目前发布的最新版本,2018 年 8 月 3 日发布的。主要是优化了接口组的使用方法、美化了 RESTFUL API 界面显示效果。最新版本可能会导致部分项目无法正常使用,这个时候需要回退到 2.X.X 版本即可。
- 导出格式灵活 : 支持 Json 和 yml 来编写 API 文档,并且支持导出为 json、yml、markdown 等格式。
- 跨语言支持性 : 只针对 API,而不针对特定语言的 API,很多自动生成 API 的工具基本都是只针对特定的 API。
- 界面清晰易懂 : 界面清晰,无论是 Editor 的实时展示还是 Swagg-UI 界面的展示都十分人性化,简单明了。
- 无法自定义界面 : Swagger-UI 封装好了一套 Html 模板,任何 RESTFUL API 的展示形式只能遵循其格式,不能灵活修改。
- 官方文档不全面 : Swagger 官方针对不同的模块提供了不同的介绍文档,但是缺乏系统的介绍,不利于新人学习。

本节是本套课程的开端,主要介绍了什么是 Swagger ,为什么使用 Swagger ,以及 Swagger 优缺点等。
本套课程主要针对 Swagger-UI 在 SpringBoot 开发框架中的使用,本节内容是学习本套课程的开端。
在本节中将为大家介绍如何使用 SpringBoot 来集成 Swagger-UI ,包括集成 Swagger-UI 的具体详细步骤,以及在集成过程中的一些注意事项。
重点讲解内容:
- SpringBoot 主流开发框架与 Swagger-UI 工具的集成步骤。
- 集成过程中的一些经验和注意事项、Swagger-UI 不同版本与 SpringBoot 框架兼容问题。
我们知道,使用 Maven 来创建的项目会有专门的一个 pom.xml 文件,这个文件是我们项目中所有用到的工具包的一个列表,在 java 中被称作 jar 包。在 Maven 中通过引入不同的 jar 包坐标配置来将相应的工具集成到我们的项目中。
所以当我们需要在项目中集成某种工具时,我们需要将该工具对应的坐标放到 Maven 的 pom.xml 文件中去。
通过访问 Maven 的中央仓库我们可以搜索到 Swagger-UI 对应 SpringBoot 框架适合的坐标数据,如下 Maven 坐标所示:
在上述 Maven 坐标中,第一个 springfox-swagger2 依赖,为 Swagger 2 的核心依赖,即我们如果想使用 Swagger 工具,则必须要在项目中引入该依赖,如果我们没有引入该依赖,那么我们是不能在项目中使用 Swagger 的。
而 springfox-swagger-ui 这一依赖,就是我们本文所介绍的 Swagger-UI 的依赖,如果我们不引入该依赖,我们是不会看到 Swagger 的 API 管理界面的。
在将上述两个 Swagger 的坐标数据放到我们项目的 pom.xml 文件中去之后,我们就完成了集成 Swagger-UI 的准备工作。
这样引入的 Swagger-UI 我们只能使用它的注解,而这时所产生的 Swagger-ui 界面我们是看不懂的,因为我们还没有对界面增加我们的规定,所以接下来让我们完成 Swagger-UI 的一些基本配置。
由于 SpringBoot 框架简化了传统 Spring MVC 框架中繁琐的 xml 文件配置,所以我们在对 Swagger-UI 进行配置时只需要使用两个注解和一个配置类即可完成,SpringBoot 为我们提供了两种配置方法,让我们来看一下吧。
Tips : 在接下来的两种配置方法中,主要介绍 Swagger-UI 的集成注解,而对于配置类我会单独进行详细讲解,请同学们注意。
Swagger-UI 官方针对 SpringBoot 框架推出了很方便的开放 API ,我们在引入了 Swagger-UI 的 Maven 坐标之后,只需要在 SpringBoot 应用的启动类的上方加入开启 Swagger-UI 的注解即可在项目中来使用 Swagger-UI。

在上图中,我添加了 @EnableSwagger2 注解,这正是 Swagger-UI 官方在 SpringBoot 框架中提供的开启使用 Swagger-UI 的注解。
当我们在项目的启动类上方添加了 @EnableSwagger2 注解之后就表示我们可以在项目中来使用 Swagger-UI 了。
Tips : 如果我们只引入了 Swagger-UI 的依赖,没有配置 @EnableSwagger2 注解,那么在项目中我们也是无法使用 Swagger-UI 的,这一点需要同学们特别注意。
对于 Swagger-UI 的配置类来说,我们只需要新建一个配置类并将该配置类通过添加 @Configuration 注解来注入到我们的项目中即可。
以上是配置 Swagger-UI 的第一种方法,即通过 @EnableSwagger2 注解与 @Configuration 注解相分离的方式来配置,这种配置方式相对来说好理解一些。
Tips:
- 各位同学在集成 Swagger-UI 时,依赖的版本请务必和老师保持一致,避免由于版本原因而出现的未知问题。
- SpringBoot 框架版本请选择 SpringBoot 2.0.X.RELEASE 及以上版本或 SpringBoot 的里程碑版本。
- @Configuration 注解贯穿整个 SpringBoot 框架,有不懂的同学请自行了解。
在第一种方式中我们将两个注解进行了分开配置,这种方法通俗易懂,而在本方式中,会将两个注解集中来配置。
我们新建一个类,名为 Swagger2Config ,这个类就是我们后续要讲的 Swagger-UI 配置类了,然后我们在该类的最上方添加上述两个注解:

在上图中,我们通过在启动类中添加 @Configuration 注解的方式将配置类以及 Swagger-UI 的所有注解来一起注入到我们项目中去,这与第一种方式的不同之处在于:
第一种方式, @EnableSwagger2 注解的声明没有通过 @Configuration 注解来处理,而是通过 SpringBoot 应用去自动装配;第二种方式则是将配置类和 Swagger-UI 的所有注解都通过 @Configuration 注解来处理,不通过 SpringBoot 应用去自动装配。
而上述两种方式并不会影响项目的正常运行,所以我们采用任何一种方式都是可取的。
在本部分中,老师将带领大家针对 Swagger-UI 常用的基本配置属性以及其他额外属性进行详细讲解,下面我们来看一下 Swagger-UI 都需要在 SpringBoot 框架中配置哪些属性(所有属性都根据官方配置演变而来)。
创建 Swagger 应用配置:

代码解释:
createRestApi 方法的返回值是一个 Docket 类型,该类型就是返回 Swagger-Documentation 类型的数据,大家不用关心。
在方法内部,使用匿名内部类的方式实例化了一个 Docket 对象并返回,DocumentationType 即文档类型的选择我们需要根据集成的 Swagger 的版本来选择,这里选择 SWAGGER_2 表示使用的 Swagger 是2.X系列版本。
apiInfo() 和 select() 这两个方法是配置 Swagger 应用的必要方法,我们只需要这样理解就可以了:集成必要的 API 信息(apiInfo() 方法)来供我们查询(select() 方法)使用。
apis() 方法里面通过 RequestHandlerSelectors.basePackage() 属性来描述我们的目标包,就是我们项目中接口所在包的完整目录名称,这样 Swagger 就可以扫描到了,如果不配置此项,Swagger 是扫描不到我们项目中的接口的。
paths() 方法就是规定将我们项目中所有接口的请求路径都暴露给 Swagger 来生成 Swagger-UI 界面。
build() 方法就是将我们设置的上述参数都放到返回的 Docket 实例中。
创建 Swagger-UI 界面基本信息配置:

代码解释:
apiInfo 方法返回 Swagger-ApiInfo 类型,大家可以理解为返回 Swagger-UI 界面的基本信息就行了。在方法内部也是通过匿名内部类的方式返回一个 ApiInfo 实例。
title() 方法:就是来规定我们的 Swagger-UI 界面的大标题。
description() 方法:就是来规定对 Swagger-UI 界面的一些简单描述信息。
contact() 方法:就是来规定创建 Swagger-UI 的作者的名称,目前已被废弃。
version() 方法:就是来规定 Swagger-UI 界面上所有接口的版本。
build() 方法:就是将我们设置的上述参数都放到返回的 ApiInfo 实例中。
通过上述两个方法的配置,我们就完成了 Swagger-UI 的基本配置,启动项目之后,在浏览器地址栏中输入访问路径(一般为项目 ip 地址:端口/swagger-ui.html)就可以在浏览器中看到 Swagger-UI 的界面效果了。

Tips:
- 访问路径中的 swagger-ui.html 为默认固定写法,一般不用修改。
- createRestApi() 方法为 public 方法,即这个方法需要对外暴露才行,而 apiInfo() 方法为 private 私有方法;该方法的用途是配置 Swagger-UI 界面基本信息,只能在项目中进行配置,不能将配置权限暴露出去。
- 在 apiInfo() 方法中我们不需要写太多的信息,因为一些必要的信息都是在接口中来描述的。

本小节从 Swagger-UI 集成准备工作开始,到不同的配置集成方式,再到最后对 Swagger 配置类的详细阐述,从零到一的对 SpringBoot 如何集成 Swagger-UI 进行了详细的讲解,旨在帮助大家能够准确的集成 Swagger-UI ,对于在集成中容易出现的问题,老师也做了相应的提醒和解决建议,希望各位同学都能成功在 SpringBoot 中集成 Swagger-UI。
针对 Swagger-UI 界面上的每一个组成元素在这里就不系统介绍了,后面会有专门的小节来对 Swagger-UI 界面的组成元素以及如何使用 Swagger-UI 进行简单必要的接口调试进行系统性地详细介绍,请各位同学关注。
本节会结合一个用户登录接口给大家介绍 Swagger 中核心注解之一 ApiOperation 及所提供的常用属性。
ApiOperation 注解在 Swagger 中扮演着非常重要的角色,基本上只要使用 Swagger 那就必须要用 ApiOperation 注解。
希望大家在学习本节过程中能够分清主次,有的放矢。
在我们日常工作中,后端小伙伴们经常会写一些接口,为了方便让大家知道这些接口的功能作用,我们就需要给接口添加一些具体的描述信息,为此,在 Swagger 中,我们就需要使用 ApiOperation 注解来描述我们写的接口。
ApiOperation 注解提供了丰富的属性来允许我们自定义接口描述信息,包括接口名称,接口所属分组等。
下面我们来看一下 ApiOperation 注解中都包括哪些主要属性。(注意:我们只介绍还在使用的属性,那些被 Swagger 官方已经废弃的属性不再介绍)。
定义:
该属性就是描述接口的作用是什么,即接口是用来干什么的。
使用方法:
在 ApiOperatio 注解中声明 value 的值即可。例如,就用户登录接口而言,只需要将 value 的值写为 '用户登录’就好了,这样我们就能很清楚的知道这个接口就是来做用户登录用的,如下代码段所示(现在你不需要理解业务代码代表什么意思,重点看方法上使用的注解及属性即可,下同)。
代码解释:
第 1 行,我们在 userLogin 方法的上方使用了 @ApiOperation 的 value 属性来描述接口的作用。
显示结果:

在结果显示界面的右上角就是我们使用 value 属性描述的信息(用户登录)。
Tips : 项目中的接口文档可能需要看的人很多,不只是开发人员看,客户有时候也要看,所以 value 属性值的描述,应该本着通俗易懂的原则进行,一定要根据接口方法实现的具体业务内容来描述,不能随便描述,不能使用表意不清楚的词语来描述,更不能使用专业术语来描述。
定义:
该属性就是对实现相同业务场景的接口做一个分组。
使用方法:
在 ApiOperatio 注解中声明 tags 的值即可,如果没有描述则默认值为空。例如,就用户登录接口而言,该接口属于用户业务分组中,所以我们将 tags 的值描述为'用户’或者'user’,这样我们就能很清楚的看到这个接口是属于用户业务组的,如下代码段所示。
代码解释:
第 1 行,我们在 userLogin 方法的上方使用了 @ApiOperation 注解的 tags 属性来描述接口所属的业务分组。
显示结果:

我们可以看到在顶部有一个 user 字样,这个就是我们规定的分组名称,也就是 tags 里写的 user 了。
Tips:
- 在实际项目开发工作中,往往一个接口可能涉及多个业务,这种情况需要我们对接口进行多个分组,而 tags 属性的类型是字符串类型的数组,可以描述一个或多个值,如存在多值时,应该使用如下方法来描述。
- tags 属性值的描述规则同上述 value 属性。
定义:
该属性就是对接口方法做进一步详细的描述。
使用方法:
在 ApiOperatio 注解中声明 notes 的值即可,如果没有描述则默认值为空。例如,如果我想添加对用户登录接口的详细描述信息,那么我可以这样写 notes = “用户登录接口必须是 post 请求”,这种使用效果会直接显示在接口面板中,当做接口的主要内容进行显示,如下代码段所示。
代码解释:
第 1 行,我们在 userLogin 方法的上方使用了 @ApiOperation 注解的 notes 属性来进一步描述接口的详细信息。
显示结果:

在我用红框圈起来的地方我们可以看到 Implementation Notes 下放就是我们对该接口的进一步详细描述,其显示在了接口的主要内容区域里面。
Tips :
- notes 属性一般用来描述接口的一些必要详细信息,如果是一般的信息则最好不要使用 notes 去描述。
- 使用 notes 属性来进一步详细描述接口这一行为往往在项目开发中不是必须的。
以上是对 ApiOperation 注解中经常使用的三个属性进行的详细介绍,value,tags,notes 这三个属性不管是在项目开发中,还是在需求沟通中,使用的都很频繁,所以,真正掌握这三个属性是用好 Swagger 的重要前提。在学习这三个属性时,大家应该自己对比并总结它们之间的差异,通过不断的使用来发现它们的使用规律,这一点很重要。
在详细讲解完 ApiOperation 重要属性之后,下面我将针对在 ApiOperation 注解中,使用频率不是很高,但是有时也会用到的一些属性做概要性讲解,这些属性分别是:httpMethod、nickname、protoclos、hidden、code。
定义:
httpMethod () 属性就是对接口的请求类型进行一个约定,常用的接口类型有:“GET”, “HEAD”, “POST”, “PUT”, “DELETE”, “OPTIONS”。
nickname () 属性是为接口起一个别名,方便前后端沟通使用。
使用方法:
httpMethod () 属性默认值为空,但是 Swagger 在处理时会默认获取项目所采用的接口请求类型,我们可以不用专门设置,如果一定要设置该属性,则只允许设置 http 协议规定的属性,不能随意设置。
nickname () 属性允许我们为接口设置一个别名,在设置别名之后,我们设置的别名会出现在浏览器地址栏中,如下代码段所示(httpMethod () 属性自动获取值,这里不再演示)。
代码解释:
第 1 行,我们在 userLogin 方法的上方使用了 @ApiOperation 注解的 nickname 属性来为接口起一个别名。
显示结果:

在我用红框圈起来的地方我们可以看到 userLoginNickName 字样,这就是我们为接口所设置的别名。
Tips :
- 不要随意定义接口的别名,要根据特定业务场景来设置。
- 在项目前后端联合测试过程中,给接口起一个别名更方便前后端开发人员的沟通,并没有其他特殊意义。
定义:
protocols () 属性就是对接口所使用的网络协议进行一个约定,常用的网络协议有:http、https。
hidden () 属性就是控制接口在 Swagger 界面中的显隐性。
code () 属性就是控制接口的返回状态,常见的有:200,201,404,500 等。
使用方法:
protocols () 属性默认值为空,但是 Swagger 在处理时会默认获取项目所采用的网络协议,我们可以不用专门设置,如果一定要设置该属性,则只允许设置 http 协议规定的属性,不能随意设置,http, https, ws, wss 这些都是被允许的。
code () 属性一般不用特定设置, Swagger 会自动生成接口返回状态,这里不再演示。
hidden () 属性允许我们在 Swagger 生成的接口列表界面上控制接口是否需要显示,默认值为 false,即接口显示,为 true 时则接口不显示,如下代码段所示。
代码解释:
第 1 行,我们在 userLogin 方法的上方使用了 @ApiOperation 注解的 hidden 属性来隐藏我们的接口。
显示结果:

可以看到在接口列表界面,已经看不到我们的用户登录接口了,这就是当 hidden 属性设置为 true 时所起的作用。
Tips :
- 接口的显隐控制应该根据特定安全策略和特定客户需求来决定显隐,不能无故隐藏接口,更不能频繁的切换接口的显隐。
- 在实际工作中,如果需要隐藏接口则需要和项目组报备情况,说明原因。
以上则是 ApiOperation 注解中的辅助使用属性的概要介绍,对于剩下的 response、responseContainer、responseReference、produces、consumes 属性在实际项目开发中几乎很少使用,在这里就不再介绍了,如果大家感兴趣可以去 Swagger 的官网查询相关资料来了解。

本小节对 Swagger 中最经常使用的 ApiOperation 注解及其该注解的各个属性做了详细的讲解,针对 ApiOperation 注解中经常在实际项目开发中使用的属性采用图文并茂的方式进行了重点介绍和应用剖析,对于一些在实际项目开发中使用基本很少的注解做了概要讲解。通过这样系统的讲解,希望大家从注解属性的定义到具体使用规范全过程中彻底搞懂 ApiOperation 注解及其注解各属性的语义规则、使用场景、注意事项等。


大家好,今天我们这个专题的主角是 — Maven。Maven 作为我们开发当中比较常见的项目管理工具,用来帮助我们构建项目,管理依赖。Maven 目前是 Apache 基金会托管的顶级项目之一,诞生自 2003 年,现在已经 17 岁了。本文当中,我们将介绍 Maven 是什么,Maven 的优缺点有哪些,为什么我们要使用 Maven。
那究竟什么是 Maven 呢,在 Maven 的官网上可以看到如下的解释:
Apache Maven is a software project management and comprehension tool. Based on the concept of a project object model (POM), Maven can manage a project’s build, reporting and documentation from a central piece of information.
翻译过来就是:Maven 是一个软件工程的项目管理工具,基于工程对象模型(POM),Maven 可以从中央信息篇中来构建项目,生成报告和文档。
从上面的介绍中,我们可以看到 Maven 的主要功能是管理项目,构建项目。
关于 Maven 的由来,据其创始人者 Jason Van Zyl 描述,是为了更加便利地建设 Jakarta Turbine 项目而创立的一个项目。在当时,比较流行的项目构建工具是 Ant,但是,在这个阶段中,各种 Java 项目之间是没有什么规范的,新创建项目的时候,就需要重新编写对应的构建脚本。Jason 就相对应设计出一套标准的项目结构,标准的构建方式,用来简化项目的构建。2003 年的时候,Maven 已经是 Apache 基金会的顶级项目了。
很多著名的项目,都是历史的产物。在当时,随着 Java 语言的流行,越来越多的项目开始使用 Java ,但是当时的构建工具并不能简单快速地完成项目构建的流程,在这种背景下,一个简单,方便,标准化的构建工具-- Maven 就产生了。
从 Maven 的官网中我们就可以看到以下几个特点:
- Making the build process easy:意思是简化构建过程,顾名思义,让构建的过程来得更简单;
- Providing a uniform build system:意思是提供统一的构建系统,Maven 提供了一个统一的构建系统。例如:Maven 使用 POM 模型以及一系列的相关插件供开发者来使用;
- Providing quality project information:意思是提供优质的项目信息,在使用 Maven 的过程中,你可以通过 Maven 来获得很多关于项目的信息,例如:已经覆盖的单元测试报告,项目的依赖列表等等;
- Providing guidelines for best practices development:意思是提供最佳实践开发指南,Maven 致力于整合开发过程中的最佳实践,并引导人们朝着这个方法前进。例如:在项目过程中 Release 版本和 snapshot 版本的管理,以及 Maven 项目标准化的项目目录结构。
总之呢,Maven 的核心是约定大于配置,它的初衷就是帮助程序开发者在最短时间内完成项目开发过程中的每个过程,目标就是更简单,更统一,更快速。
- Maven 的整个体系相对庞大,想要完全掌握相对困难;
- 如果项目的依赖过多,在第一次导入项目的时候需要花很长的时间来加载所需要的依赖;
- 由于某种不可抗拒力,国内的开发者在使用 Maven 中央仓库的时候,下载速度过慢。
但是,这些问题都是有可以有解决办法的,我们后续会慢慢一一介绍。
在 Java 开发的世界中,有三大主流的构建工具,分别是 Ant ,Maven ,Gradle。
其中 Ant 出现的世界最早,能够提供编译、测试、打包的功能,但是 Ant 缺乏对依赖的管理,以及标准的项目结构。
后来 Maven 的出现,解决了 Ant 所不能满足的两个问题,从创建项目到构建及发布项目的整个过程定义了一套完整的规范,并且提供中央仓库,对依赖进行管理。
后来,随着 Android 的流行,近年来,以 Gradle 作为项目的构建工具也越来越流行。Gradle 在 Maven 的基础上,使用基于 Groovy 的特定领域语言(DSL)来完成配置声明,相较于 XML 来说,更加灵活。目前,Maven 和 Gradle 基本上算是平分秋色的局面,在实际的开发中,后台项目管理更倾向于使用 Maven,而在移动端开发中,Gradle 的占比更大。当然两者之间也有很多相通的地方,比如依赖管理,一致的项目结构。
Maven 从发布到现在已经经历过很多个版本迭代,目前最新的版本是 2019-11-25 发布的 Maven 3.6.3 版本。
- 1.0-2.x : 官方不再进行维护,也不建议开发者使用;
- 3.0: Maven3.x 的第一个版本,也算是 Maven 的里程碑版本,完全向后兼容 Maven2,增加了 SLF4J 来进行日志管理,并且提高了项目构建效率和插件的扩展性;
- 3.5.0: 该版本显著的变化是 Maven 的控制台支持不同级别日志输出不同颜色;
- 3.6.3: 目前的最新版本,schemaLocations 地址支持 https。在后续的章节中,我们也会用这个版本来进行讲解。
说到这个问题,我们首先要看一下,如果没有 Maven,那么我们的工作是什么样子的呢?
场景一
当我们在开发过程中,当我们开发某个新功能或者修复了某个 Bug,都需要手动进行整个项目编译,运行单元测试,生成项目文档,打包,部署环境这些步骤。一旦需要重新修改代码的时候,便要将上述的操作重复一遍。机械性的重复劳动充斥着整个开发过程;
场景二
由于不同的人可能会有不同的习惯或者说是个人偏好,每当我们新建一个项目的时候,所建出来的项目可能会千奇百怪,这也给后续的维护升级带来了诸多的不便;
场景三
当项目需要依赖某个 jar 包的时候,需要到互联网上去寻找对应的 jar 包,找到 jar 包之后,将这个 jar 包添加到项目的 lib 目录下,项目组里面不同的人可能会找到不同的 jar 包,不同的 jar 包直接可能会存在冲突,这个时候,就需要去手动解决冲突;
看到这里,只想说一句,我太难了。但是,不要慌,Maven 的存在,就是为了帮助解决这些问题。
使用 Maven 之后,只需要执行一个命令就可以完成编译,运行单元测试,打包,部署的整个流程;并且 Maven 以 POM 的形式来管理 jar 包依赖;还有一点就是,使用 Maven 构建出的项目,结构统一,方便后续的维护升级。
本教程当中使用了一些 Java 项目作为例子,所以需要了解简单的 Java 基础。
在本课程中,我们首先会对 Maven 的核心概念进行讲解,并且,通过一些简单的项目,来加深对这些概念的理解,在课程的过程中,如果遇到平时工作时常使用的点,则会穿插一些实际工作中的最佳实践,方便在工作中能够学以致用。
在上一节中,我们对 Maven 有了一个大概的了解,了解到 Maven 有很多优点,那么我们今天就来介绍,如何在 Windows 环境中安装和配置 Maven。在教程中,我们使用的 Maven 版本是 3.6.3 版本,jdk 版本是 1.8。
首先在 Maven 官网上,找到下载地址,并下载该版本apache-maven-3.6.3-bin.zip,如下图所示:

由于 Maven 是使用 Java 开发的工具,因此需要先安装 jdk。Maven3.6.3 版本需要 jdk1.7+ 版本来支持,本教程使用的是 jdk1.8 版本。
Tips:jdk 的安装过程在这里我们就不多赘述了,同学们可以参考下慕课网相关 Wiki 进行安装。
打开 cmd 运行窗口输入:,如下图所示,能够正常查看 Java 版本信息即说明 jdk 安装成功:

将 Maven 的安装包复制到指定目录中,并解压该安装包。解压后在 Maven 的 bin 目录下进入 cmd,输入 mvn -v,可查看 Maven 版本信息。

但是,现在我们只能在 Maven 的 bin 目录下执行 mvn 命令,无法随时随地使用 Maven,因此,我们需要将 Maven 的路径配置到环境变量当中。

新增了 MAVEN_HOME 之后,需要将 %MAVEN_HOME%bin 追加到 path 当中,需要注意的时候,追加的时候需要在前面加一个 和 path 中之前我们添加的环境变量做一个分割:

在追加完 path 之后,我们在任意目录下执行 mvn -v 命令,都可以正常查看 Maven 版本信息,即为配置成功。

在 Linux 系统中,需要使用 tar 包来进行安装。我们可以去官网下载对应安装包(apache-maven-3.6.3-bin.tar.gz),也可以使用 Linux 系统中的 wget 工具来进行下载。这里我们使用 wget 工具来进行下载。
我们可以从阿里云的镜像站中下载,速度更快些。
进入到需要下载的目录,我们这里的目录地址是,进入该目录后,执行 wget 命令,。
执行
打开配置文件 在文件的最后添加如下配置:
保存文件后,执行 命令。
此时,切换到任意目录下,执行命令 。可以看到当前 Maven 的版本信息。

在 Mac 环境中安装 Maven 和在 Linux 环境下安装 Maven 的步骤和过程大体是相同的,只不过在 Mac 环境中的环境变量文件位置是 `~/.bash_profile``,所以在这个文件中添加环境变量即可。
我们在将 Maven 安装好之后,为了方便我们后面的使用,可以对 Maven 进行简单的配置。
进入 Maven 路径下的 conf 目录,打开 setting.xml 文件。
在 Maven 的使用过程中,会自动将项目依赖的 jar 包从中央仓库下载到本地仓库,默认本地仓库路径是,这样的话,会占用较多的 C 盘空间,因此,我们可以自定义该路径。

由于 Maven 中央仓库的服务器是架设在国外的,所以由于某种不可抗拒力量,国内用户如果直接使用中央仓库的话,下载速度会受很大的影响。如下图所示,个人用户可以使用阿里云镜像。这里阿里云仓库是作为中央仓库的一个镜像的,镜像库会完全屏蔽被镜像库。

镜像地址:
经过上面的简单配置之后,我们就可以开心地使用 Maven 了。
配置好 Maven 之后,接下来我们就可以使用 Maven 来创建我们的第一个项目了。
在 cmd 中切换到我们存放代码的目录,并执行如下命令:
参数说明:
- -DgourpId: 组织名,一般为公司网址的反写;
- -DartifactId: 项目名-模块名;
- -DarchetypeArtifactId: 用来指定 ArchetypeId,这里用到的是maven-archetype-quickstart,即创建一个简单 Java 应用;
- -DinteractiveMode: 是否使用交互模式。
项目创建好之后,会有如下提示:

Tips:由于是第一个Maven项目,在创建的时候,需要下载 Maven 插件,所以耗时会相对长一点。
接下来,我们将该项目导入到 Idea 中,来查看该项目。

点击运行后,可以正常输出 Hello World!
Your browser does not support the video tag.
Your browser does not support the video tag.
本节,我们主要讲了如何在 Windows 环境下安装 Maven 以及修改简单配置,并且使用 Maven 创建运行了一个 Java 应用。
5. 小结
本节中,我们介绍了 Maven 中的一个重要的概念–依赖,介绍了什么是依赖,以及依赖的几个特性,最后我们也总结了在平时的工作中常常会用到的依赖优化的方式,能够帮助我们更好的管理项目的依赖。
在上一节当中,我们使用 Maven 创建了我们的第一个项目,今天我们来介绍一下 Maven 中重要的概念 POM 模型。
POM(项目对象模型)是 Maven 最基本,也是非常重要的一个概念。通常情况下,我们可以看到 POM 的表现形式是 pom.xml,在这个 XML 文件中定义着关于我们工程的方方面面,当我们想要通过 Maven 命令来进行操作的时候,例如:编译,打包等等,Maven 都会从 pom.xml 文件中来读取工程相关的信息。
我们在 cmd 中打开项目根目录,执行 命令。可以看到如下图的项目结构:

- 每个项目都有一个 pom.xml 文件,该文件中定义本项目的对象模型,描述本项目,配置插件,声明依赖;
- 对于简单的 Maven 项目, 目录放置项目的源码和资源文件,一般情况下,源码放置在 Java 目录下,App.java 就是 Maven Archtype 插件生成的一个简单类,classpath 资源文件放置在resources 目录下。
- 目录下放置我们的测试用例,与 main 目录类似, 目录下放置我们的测试类源码, 则是 Maven Archtype 插件生成的一个简单测试类, 放置测试用到的 classpath 资源文件。
注: 这里 Maven 只是帮我们创建了一个简单的 Maven 项目,其中 resources 目录则需要手动创建。
我们打开项目中的 pom.xml 文件,如下图:

现在看到的这个 pom.xml 是 Maven 项目中最基础的 POM,后面随着项目的慢慢的进行,这个 pom.xml会变得更加复杂,我们可以向其中添加更多的依赖,也可以在里面配置我们需要的插件。
从头开始看:groupId,artifactId,packaging,version 几个元素是 Maven 的坐标,用来唯一标识一个项目。
接下来是 name,url 这两个元素则是用来描述信息,给人更好的可读性。
最后是 dependencies,这里 Maven 默认依赖了 3.8.1 版本的 junit,其中 scope 用来标记该依赖的范围为 test。
接下来我们就重点介绍一下 Maven 的坐标(Coordinates)。

- groupId:groupId 为我们组织的逆向域名,这里的组织可以是公司,团体,小组等等。例如Apache 基金会的项目都是以 org.apache 来作为 groupId 的;
- artifactId:该组织下,项目的唯一标识;
- packaging:项目类型,描述的是项目在打包之后的输出结果,常见的 jar 类型的输出结果是一个jar 包,war 类型则输入 war 包,一般 Web 项目的打包方式为 war。
- version:项目的版本号,用来标记本项目的某一特定版本。SNAPSHOT 则是用来标记项目过程中的快照版本,该版本类型表明本项目不是稳定版本,常见的还有 RELEASE,则表示该版本为本项目的稳定版本。
在我们这个项目的 pom.xml 文件中,只有短短的几行信息,但是这就全部吗?其实不然。
在 Maven 的世界中,存在着一个超级 POM(super POM),所有通过 Maven 创建的项目,其 pom.xml 文件都会继承这个超级 POM。所以在默认情况下,使用 Maven 创建出来的项目基本上都是很类似的。
那么这个超级 POM 在哪呢?长什么样呢?
如下图,先找到指定的 jar 包,路径::

然后我们可以使用解压工具查看该 jar 包,找到对应的 pom.xml。

具体路径:。
对于我们的项目,我们称超级 POM 为父 POM,我们项目中的 POM 为子 POM,一般情况下如果父子 POM 中存在相同的元素或者节点,那么子 POM 会覆盖父 POM 的元素或者节点(有点类似 Java 中的 override),但是,也会有这么几个例外存在:
- dependencies;
- developers 和 contributors;
- plugins;
- resources。
子 POM 在继承这些元素的时候,并不会直接覆盖,而是在其基础上继续追加。
本节中,我们介绍了 Maven 的 POM 模型,查看 Maven 工程的 pom.xml 文件,以及 pom.xml 文件中的坐标,最后我们还介绍了超级 POM,这样,我们就对 Maven 的 POM 模型有了一个基本的认识。
在上一节中,我们重点介绍了 Maven 的项目对象模型(POM),本节我们重点介绍另一个重要概念–依赖。我们会介绍什么是依赖,以及在我们平时的工作中的最佳实践。
依赖即为本项目对其他项目的引用,这里的其他项目可以是外部项目,也可以是内部项目。我们在开发项目的过程中,将其他项目作为依赖引用进来,最终在打包的过程中,依赖会和我们开发的项目打包到一起来运行。
在我们的项目没有使用 Maven 的时候,我们需要手动去管理我们的依赖,例如:添加依赖,删除依赖。在使用了 Maven 之后,我们可以在 pom.xml 文件里面看到我们所有的依赖,并且可以灵活的管理项目的依赖。

Maven 在编译和运行以及执行测试用例的时候,分别会使用不同的 classpath。而 Maven 的依赖范围则是用来控制依赖与不同 classpath 关系的。
Maven 的依赖范围分为以下几种:
- compile: 编译依赖范围。Maven 默认的依赖范围,该范围的依赖对编译,运行,测试不同的classpath 都有效。例如我们项目中的 spring-boot-starter;
- test: 测试依赖范围。该依赖范围只对测试 classpath 有效,在编译项目或者运行项目的时候,是无法使用此类依赖的。例如我们项目中的 spring-boot-starter-test;
- provided: 已提供依赖范围。该 Maven 依赖对于编译和测试的 classpath 有效,但是在运行时无效;
- runtime: 运行时依赖范围。顾名思义,该依赖范围对测试和运行的 classpath 有效,但是在编译时无效;
- system: 系统依赖范围。该依赖范围与 classpath 的关系与 provided 依赖范围是相同的。但是,在使用时需要谨慎注意,因为此类依赖大多数是与本机绑定的,而不是通过Maven仓库解析出来的,切换环境后,可能会导致依赖失效或者依赖错误。
目前我们的项目只引用了两个依赖,spring-boot-starter 和 spring-boot-starter-test,但是是这样子的吗?
为了能够更清晰的看到我们项目依赖的结构,我们可以在 IDEA 里面安装 Maven Helper 插件。


从这里我们就可以看到,其实我们不只是引入了两个包,而是引入了很多个包,这是为什么呢?
答案是因为 Maven 的传递性依赖机制。
在我们这个项目中,我们引入了 spring-boot-starter 依赖,并且该依赖的范围是 compile,但是 spring-boot-starter 作为一个项目也有自己的依赖,在这其中的依赖范围为 compile 的依赖,则会自动转换成我们项目的依赖,例如 spring-boot 依赖,logback-core 依赖。
所以,有了 Maven 的传递性依赖机制之后,我们在使用一个依赖的时候,就不再需要考虑它又依赖了哪些,而是直接使用即可,其他的事情 Maven 会自动帮我们做完。
有了传递性依赖能够大大节省我们在管理依赖时候所耗费的精力。但是,如果传递性依赖出了问题我们应该如何解决呢?首先,我们应该知道的是传递性依赖是从哪条依赖路径引用进来的。
在我们的项目中就存在这样的例子。我们可以看到如下两条不同的引用路径:
1.
2.
这个时候,我们可以看到,两条路径最终引用的 spring-core 版本都是 5.2.5-RELEASE。但是如果引用的 spring-core 版本不同,Maven 会怎么做呢?
使用最短路径原则,路径2中的 spring-core 版本会本引用,这样就不会造成重复依赖的问题产生。
传递性依赖可以帮助我们简化项目依赖的管理,但是同时也会带来其他的不必要的风险,例如:会隐式地引入一些依赖,这些依赖可能并不是我们希望引入的,或者这些隐式引入的依赖是 SNAPSHOT 版本的依赖。依赖的不稳定导致了我们项目的不稳定。
在我们的项目中,spring-boot-starter-test 依赖中排除了 junit-vintage-engine 依赖是由于我们使用的 springboot 版本是 2.2.6-RELEASE,对应的 Junit 版本是 5.x,但 junit-vintage-engine 依赖中包含了 4.x 版本的 Junit,此时我们就可以将该依赖排除。
在 exclusions 标签中,可以有多个 exclusion 标签,用来排除不需要的依赖。
在我们实际的开发过程中,我们可能会需要整合很多第三方框架,在整合这些框架的时候,往往需要在 pom.xml 里面添加多个依赖来完成整合。而这些依赖往往是需要保持相同版本的,在升级框架的时候,都是要统一升级到一个相同的版本。
如下图,我们可以看到,在引入 dubbo 框架的时候,我们需要引入两个相关的依赖,而且版本号是相同的,这个时候,我们就可以把对应的版本号提取出来,放到 properties 标签里面,作为一个全局参数来使用。类似于 Java 语言中抽象的思想。

这时候,我们可以看到,如果在将来的某一天我们需要升级升级 dubbo 框架对应的版本,只需要修改 properties 中的版本号,就能将所有依赖的版本一起升级。
我们再回过头来看一下 Maven Helper 工具所展示的场景

我们在这个工具中可以看到我们项目现在引入的所有的依赖,可以看到哪些是我们用到的,哪些是没有用来的,依赖与依赖之间是否存在冲突。如果出现了上述情况,我们就可以通过删除或者依赖排除的方式来将我们不需要的依赖删除掉,从而使我们的项目更简洁。
本节中,我们介绍了 Maven 中的一个重要的概念–依赖,介绍了什么是依赖,以及依赖的几个特性,最后我们也总结了在平时的工作中常常会用到的依赖优化的方式,能够帮助我们更好的管理项目的依赖。
在之前的章节中,我们分别介绍了 Maven 中的工程对象模型(POM)以及 Maven 的依赖管理,但是,这个时候,我们势必会有一个疑问,当我找到一个依赖的坐标后,只需要将该坐标放入到我项目的 POM 文件当中,这个依赖就算是被引入了,那这个依赖是从哪里来的呢?
在本节中,我们就带着这个疑问来学习 Maven 的仓库,了解如何使用 Maven 仓库。
我们先想象一下,如果没有 Maven,我们在开发不同项目的时候,如果需要依赖同一个 jar 包,那么就需要分别在两个不同项目中将这个 jar 包引入进去,对于一个程序员来说,这样的做法显然是不合理的,不仅需要我们手动到处复制,而且会多占用我们的磁盘空间。
那这个时候,Maven 仓库就出现了。我们通常把依赖称为构件,每一个构件都有自己唯一的坐标,基于这种模式,我们就可以把这些构件存放在一个指定的位置–Maven仓库当中,然后通过其坐标来寻找该构件。
在我们学习或者实际开发过程中,只需要在我们的项目当中声明依赖的坐标,在项目编译的或者打包的过程中,Maven 会自动从仓库中去寻找该构件,这样就不需要我们在本地存储这个依赖了。
对于 Maven 来说,主要的仓库种类可以分为两种,一种是本地仓库,另一种是远程仓库。而在远程仓库当中呢,又可以分为中央仓库,私服和其他的公共仓库。

在我们声明的 MAVEN_HOME 路径下,找到 ,其中可以看到 Maven 的本地仓库路径配置:

从上图我们可以看到,Maven 的默认本地仓库路径是在 ,我们为了方便将其修改为了 。
Maven 中默认配置了中央仓库,我们可以在超级 POM 里面找到对应的配置。

这个仓库是由 Maven 社区来维护的,里面存放了绝大多数开源软件的包,并且是作为 Maven 的默认配置,不需要开发者额外配置。另外为了方便查询,还提供了一个查询地址,开发者可以通过这个地址更快的搜索需要构件的坐标。
有了中央仓库,我们为什么还需要其他的远程仓库呢?
- 我们要找的构件可能不存在于中央仓库中;
- 由于某些原因,访问中央仓库的速度相对较慢。
这种时候,我们就可以选择一个使用起来相对方便的远程仓库来配置,大大提高了我们的开发效率。
国内常用的 Maven 仓库:
阿里云镜像:
阿里巴巴镜像:
repo2 镜像:
我们可以将对应的仓库的镜像配置到 settings.xml 文件中的 mirrors 节点中即可。如下图所示,我们配置了阿里云的镜像。

私服也是属于远程仓库的一种,相对公共仓库而言属于某个公司或者某个开发团队私有的远程仓库。通常部署在某个局域网内,提供局域网的内部用户使用。
那私服有什么好处呢?
- 更快的下载速度:由于是局域网内部的请求,因此下载构件的速度是可以保证的;
- 更稳定的构建:想象一下,如果我们依赖某个外部的远程仓库,当这个仓库出现不可能用的情况,哪怕是网络的波动,都有可能会造成我们的构建失败;
- 部署第三方构件:如果一个公司使用了微服务架构,那么公共仓库是肯定没办法获取这些私有的构件的。
当我们需要一个构件的时候,Maven 会先去请求私服,如果发现私服中,没有该构件,那么就会去配置了的远程仓库中寻找,并且缓存到我们的私服中,为后续的下载请求提供服务。
我们知道了 Maven 通过坐标去仓库中寻找对应的构件,那么这个机制的原理是怎么样的呢?
Maven 在寻找需要的依赖的时候,会遵照下面的顺序:
- 如果构件的依赖范围是 system,Maven 会直接从本地的文件系统来解析该构件;
- 根据配置的依赖坐标,在本地仓库中寻找该构件,如果能够搜索到,则解析成功;
- 如果本地仓库没有搜索到,那么就会去已经配置了的远程仓库中搜索该构件,搜索到后,下载到本地仓库中,提供项目使用;
- 如果依赖的版本是 RELEASE 或 LATEST,那么就会根据更新策略去读取所有远程仓库中的元数据信息(groupId/artifactId/maven-metadata.xml),并且与本地仓库中对应的元数据合并后,计算出真实值,再将其下载到本地仓库中;
- 如果依赖的版本是 SNAPSHOT,那么就会根据更新策略去读取所有远程仓库中的元数据信息(groupId/artifactId/version/maven-metadata.xml),并且与本地仓库中对应的元数据信息合并后,得到最新的快照版本值,根据这个值去寻找对应的依赖;
- 解析出的快照版本一般是带有时间戳的,下载下来后,会将该时间戳删掉,以无时间戳的形式来使用。
在本节中,我们介绍了什么是 Maven 仓库,主要的仓库分类以及不同仓库的特点。最后我们还介绍了从 Maven 仓库中的依赖解析机制。
我们今天带来的是 Maven 的另一个重要概念–生命周期。在学习了 Maven 的生命周期之后,在使用 Maven 的过程中,就能够够好的理解每一步操作的意义。
其实生命周期这个概念并不是 Maven 首创的,因为即使不用 Maven,这些事情也是需要我们去做的。想象一下在没有 Maven 的时候,我们开发完一个项目之后,一般是直接使用 Java 的相关命令进行编译,打包等等工作。
但是这些工作无聊而且繁琐,基本上充斥在开发者每天日常的工作中,无论是开发新功能,还是修改一个 Bug,都需要重复以上操作。当然有聪明的开发者,也会将这些每天重复的事情做成脚本来执行。
那么问题又来了,不同公司的不同项目之间或多或少会存在些许差异,这种时候,可能就需要开发者针对这些差异来定制一些步骤,或者脚本。也就是说,每当我们开始开发一个新项目的时候,或者换到另一个项目组的时候,我们构建项目的步骤或者方式都可能会发生变化。
Maven 的出现,可以说是很大程度上缓解了这种问题的发生。通过吸取很多项目的经验,Maven 定义了一套完整而且统一的生命周期模型。使用这个模型,我们将构建的细节交给 Maven,只需要理解对应生命周期的含义即可完成构建。就好像,人到了青少年的时候,就要去上学,到了青年的时候,就要出来工作类似,我们不需要知道上学或者工作中具体的事情,只需要知道,到了这个阶段,能够做这个事情就可以了。
Maven 的生命周期并非只有一套,而是有三套,并且这三套生命周期之间是没有关系的。一套生命周期包含很多个不同的阶段,这些不同的阶段是有顺序的,有些阶段必须要在某个阶段完成之后,才能进行。Maven 的三套生命周期分别为:clean(清理),default(默认),site(站点)。接下来我们就一一介绍一下这三个生命周期。
clean 生命周期包括:
- pre-clean:清理前的准备工作;
- clean:清理上一次构建的结果;
- post-clean:清理结束后需要完成的工作。
一般情况下,Maven 的构建结果会生成在 target 目录下,我们执行 mvn clean 命令后,这个目录会被清空。

从上图,我们可以看到,对应的 target 目录被清理干净了。
default 生命周期应该算是大多数开发者最为熟悉的生命周期,也是平时在开发过程中最常用的生命周期。

(clean,site 并不属于 default 生命周期)在 default 生命周期中,最常用的几个阶段包括:
- validate:验证阶段。验证项目构建过程中需要的信息的正确性;
- compil:编译阶段;
- test:测试阶段。使用测试框架对项目进行测试,打包过程中,非必要阶段,可以跳过执行。
- package:打包阶段。将编译好的文件打包成 jar 包,war 包或者 ear 包;
- verify:检查阶段。检查打包结果的有效性;
- install:本地部署阶段。将包部署到本地仓库,可以提供给本地开发过程中其他项目使用;
- deploy:远程仓库部署阶段。将最终的包复制到远程仓库,提供给使用该仓库的其他开发者使用。
这里我们介绍的只是在 default 生命周期中最常用的,其实在这些阶段执行的过程中,还会有其他的阶段需要执行,但是并非很常用。另外,不出意外的情况下,在生命周期中,后执行的阶段要等先执行的阶段执行完再执行。

我们试着执行 Maven 的打包命令:。执行完成之后,可以看到其所经过的生命周期。因此,当我们想要构建项目的时候,并不需要分别执行 package 阶段之前的阶段,而是 Maven 自动为我们执行。突然发现,原来构建项目是如此的简单,方便。
很多时候,我们不仅仅需要构建我们的项目,还需要生成项目文档或者站点。site 生命周期则是来帮助我们做这件事情的,它能够根据我们项目中 pom.xml 的信息,来生成一个友好的站点。
跟其他的生命周期一样,site 生命周期也包含不止一个阶段:
- pre-site:准备阶段。在生成站点前所需要做的工作;
- site:生成站点阶段;
- post-site:结束阶段。生成站点结束后所需要做的工作;
- site-deploy:发布阶段。我们可以将上面生成的站点发布到对应服务器中。
其实在 Maven 的世界中,生命周期只是一个抽象的模型,其本身并不会直接去做事情,真正帮我们完成事情的是 Maven 的插件。Maven 的插件也属于构件的一种,也是可以放到 Maven 仓库当中的。
通常情况下,一个插件可以做 A、B、C 等等不止一件事情,但是我们又没有必要为每一个功能都做一个单独的插件。这种时候,我们一般会给这个插件绑定不同的目标,而这些目标则是对应其不同的功能。

当我们使用一个插件的目标的时候,我们可以执行命令:。例如当我们执行插件的 list 目标的时候,我们可以执行命令:。

使用该插件目标,我们可以看到目前我们项目中所有依赖的情况。
我们说 Maven 的生命周期只是抽象的概念,真正帮我们完成事情的是插件,其实更确切的说,应该是生命周期与插件对应的目标绑定,来完成具体的功能。

在本节中,我们详细介绍了 Maven 的生命周期,常用的生命周期,以及其与插件的对应关系,简单的工作原理。学完之后,能够加深 Maven 的理解,减少使用过程中的误解。
本节中,我们来介绍一下 Maven 是如何进行版本管理的。如何在项目的实际开发中,结合 Maven 来推进项目的进行。一个正常的项目的开发周期通常是很长的,这个过程当中,需要发布很多个版本,那这些版本如何表示,而我们又应该如何来管理这些版本呢?
那什么是版本管理呢?首先,版本管理是不同于版本控制的。版本控制通常的概念是在软件开发过程中,管理程序文件,配置文件等文件的变化。更倾向于来追踪一个项目过程中,不同时期项目的变化。但是,版本管理则不同,通常是指一个项目过程中,不同时期版本的演化过程。通俗一点讲,版本管理就像人的成长过程中,从婴儿到少年到青年到中年一直到老年这个演变过程的管理;版本控制则更关注细节,例如这个时期,身高从 160cm 长到了 165cm,或者体重 60kg 变为了 62kg 等等。
我们理解了什么是版本管理,那 Maven 是如何做的呢?
通常情况下,Maven 的版本号约定中包括如下几个部分:
<主版本号> . <次版本号> . <增量版本号> . <里程碑版本号>里程碑版本号> 增量版本号> 次版本号> 主版本号>
- 主版本号:主版本号表示该项目的重大升级。例如:Maven1 到 Maven2;
- 次版本号:表示在该主版本下,较大范围的升级或变化。例如:Maven-3.0 到 Maven-3.1;
- 增量版本号:增量版本通常是用来修复bug的版本。例如:Maven-3.1.1;
- 里程碑版本号:用来标记里程碑版本。例如:Maven-3.0-alpha-3。
由于 Maven 已经维护了将近 20 年,所以,使用 Maven 这个项目的版本演变过程来举例是再合适不过了。我们打开 Maven 的官网,找到 Release Notes,打开便可以看到 Maven 从最开始的版本是如何演变成现在的模样的。(这里由于存在太多版本,所以,我们只截取了其中一部分)

(Maven 版本演变历史列表)
注意: 有的同学可能会问,里程碑版本里面的 alpha,beat 是什么意思?
- alpha 版本: alpha 版本被称为是内测版本。通常会存在比较多 bug,主要是面向测试人员使用;
- beat 版本: 这个版本也是测试版本。会比 alpha 版本新增加一些功能;
- RC 版本: 即将发布的候选版本。这个阶段不会再新增功能,主要用于修复 Bug;
- GA 版本: 正式发布版本,也可以对应于 release 版本。
这些版本号在一些流行的框架的演变过程中非常常见。
通常情况下,我们在进行项目开发的过程中,会使用到版本控制工具,例如 svn 或者 git,这时候就会涉及到主干,分支以及标签的概念,那么这里我们简单介绍一下这三个概念。
- 主干: 通常是项目代码的主体。会存在于整个项目周期中,其他的所有分支都是从这里开始的,一般情况下,项目最新的源代码或者所有的变更记录都可以在这里找到;
- 分支: 从主干中某个节点分离出来的代码。在分支刚刚创建的时候,具有当时主干中所有的源代码。通常分支是为了修改某些 Bug 或者进行一些其他的开发,这些源代码的修改并不会影响主干。一旦这个分支中的代码验证通过后,可以将代码归并到主干中去;
- 标签: 通常用来标记主干或者分支中某个时间节点的状态,
从下面的图中,我们可以比较清晰地看出,主干,分支与标签三者之间的关系:

主干,分支与标签三者关系图
我们在了解了主干以及分支的概念之后,那么我们如何去创建分支呢?通常情况下我们可以使用 Svn 或者 Git 自带的创建分支的方式来创建需要的分支,但是,这个时候会存在一个问题:我们需要手动去修改新创建出的分支的 pom.xml 文件中的内容。既然说到版本管理,那想必 Maven 肯定是可以帮助我们做这件事情的。
那么接下来我们来看一下如何使用 Maven 来创建分支,这里我们使用 Git 配合 Maven 来演示如何创建分支。
我们想要使用 Maven 来帮助我们创建分支,首先我们需要配置 scm ,这样 Maven 就可以来代替 Git 来进行操作。
这里我们在 gitee 上创建一个仓库来放置我们的项目。
1. 将 scm 配置到 pom.xml 文件中:
2. 将 maven-release-plugin 插件配置到 pom.xml 文件中:
3. 执行 命令:
- -DbranchName: 目标分支。这里我们可以根据需要来自定义新分支的命名结构;
- -DupdateBranchVersions: 在分支中更新版本;
- -DupdateWorkingCopyVersions: 在当前分支更新版本。
在执行的时候, Maven 会问 branch version 是否为 1.0.1-SNAPSHOT?这个是我们想要的,直接 enter 即可。
执行完成之后,我们查看 Git 的远程仓库中,可以看到新生成的分支。

4. 执行 命令:
在执行的时候,Maven 会问 release version 是否是 1.0.0?这个是否是我们想要的,直接选择 enter 即可。
紧接着,Maven 会问我们 release tag 是否是1.0.0-SNAPSHOT?这个也是我们想要的,直接 ente r即可。
紧接着,Maven 会问我们新的版本是否是1.0.1-SNAPSHOT?这里输入新版本为1.1.0-SNAPSHOT,然后 enter。
执行成功之后,我们更新一下代码,会发现,主干上的 pom.xml 文件的版本已经升级为1.1.0-SNAPSHOT了。
本节当中,我们着重介绍了在 Maven 的世界中,我们一般是如何来约束版本的,以及这些约束所代表的含义,最后,我们还介绍了如何使用 Maven 来管理这些版本。
通常情况下,我们在实际开发过程中,会对项目进行模块(module)划分,来提供项目的清晰度并且能够更加方便的重用代码。但是,在这种时候,我们在构建项目的时候就需要分别构建不同的模块,Maven 的聚合特性能够将各个不同的模块聚合到一起来进行构建。而继承的特性,则能够帮助我们抽取各个模块公用的依赖、插件等,实现配置统一。
这里我们以一个简单的 mall 项目作为例子。先来看一下这个项目的结构,整个项目包括 mall-core 和 mall-account 两个功能模块和 mall-aggregator 一个聚合模块。其中, mall-core 处理商城项目的核心业务逻辑, mall-account 用于管理商城的账户信息。

项目文件图示
一般来说,对于只有一个模块的项目,我们可以在该模块下直接执行 命令来进行项目构建,但是,对于这样的多模块项目,我们如果要构建不同模块的话,需要分别在对应模块下执行 Maven 的相关命令,这样看起来是非常繁琐的。这个时候,Maven 的聚合特性就能够起到作用。
我们来分析一下这个项目整体的结构,首先,我们看一下 mall-aggregator 模块。这个模块作为整个工程的聚合模块,并没有实际的代码,但是其本身也是一个 Maven 项目,所以,也会存在 pom.xml 文件。那我们首先来看一下这个 pom.xml 文件有什么特点。

mall-aggregator 模块的 pom.xml 文件
我们可以看到这里面也会有相对应的 groupId , artifactId , version ,packaging 信息,其中 packaging 的值必须是 pom,否则聚合项目无法构建。我们从 modules 中可以看到整个项目包含两个模块,分别是 mall-core 和 mall-account 。通常情况下,我们将不同的模块放到聚合模块下,其中 module 的值分别对应不同模块的 artifactId 值。
在这个时候,我们 mall-aggregator 模块下,使用 来进行构建,可以将两个模块同时打包完成。
从这次构建的过程来看,我们可以看出,Maven 会首先解析聚合模块的 pom.xml 文件,分析出有哪些模块需要构建,进而计算出一个反应堆构建顺序(Reactor Build Order),并且根据这个顺序来依次进行模块的构建。
现在我们解决了同时构建不同模块同时构建的问题,但是,对于多模块项目来说,还是会有些其他的问题存在,例如,不同模块间有相同的 groupId,version ;有时候,也会需要引入相同的依赖。这个时候,如果每个模块都重复引入的话,结果就会造成冗余。作为一个遵循面向对象的程序员来讲,这样的做法显然是不合理的。
因此,Maven 也引入了类似的机制来解决这个问题,就是继承的特性。
类似于 Java 中的父类与子类,我们也可以创建一个父模块,让其他的模块作为子模块来继承该模块,从而继承父模块中声明的依赖以及配置。
对于父模块来说,只是作为配置的公共模块,是不需要代码的,而且 pom.xml 文件中的 packaging 方式也是 pom,因此,我们可以将聚合模块同时作为父模块来使用,没有必要再创建一个父模块。(当然,这里也是可以单独创建父模块的)
此时,我们查看 mall-core 或者 mall-account 的 pom.xml 文件。


mall-core 模块的 pom.xml 文件
我们可以看到 mall-core 模块继承了父模块的坐标信息,并重新定义了 artifactId 。这时候,我们在父模块引入一个依赖,然后查看 mall-core 模块的 pom.xml 文件,会发现,在 mall-core 模块中也会引入这个依赖。但是,实际上,我们并没有在 mall-core 模块中显式的声明这个依赖。

其实问题并没有完全解决,并不是所有的子模块都需要引入 fastjson-1.2.49.jar 这个依赖,那要怎么办呢?
在 POM 中,我们可以在父模块中声明 dependencyManagement 元素,让子模块来继承。dependencyManagement 元素并不会实际的引入依赖,但是可以起到很好的约束依赖的作用。
首先,我们在父模块的 pom.xml 文件中声明这个元素,并加入 fastjson-1.2.49.jar 这个依赖。
然后,我们在 mall-core 模块中添加这个依赖,但是我们并不需要再声明version。
这时候,我们分别查看父模块与子模块所引入的依赖,会发现,只有子模块中有引入这个依赖,而父模块中,并没有。

父模块依赖引入情况而子模块中已经引入了这个依赖。

子模块依赖引入情况
我们通过 Maven 继承的特性,来进行依赖管理,可以更好的控制依赖的引入。而 Maven 对于插件的管理,也存在类似的元素可以使用(pluginmanagement 元素),可以做到相同的效果。
反应堆指的是整个项目中所有模块的构建结构。在本节的例子中,整个构建结构包括三个模块。反应堆不仅仅包括模块本身,还包括了这三个模块直接的相互依赖关系。
现在,我们的示例项目中,mall-core 和 mall-account 是不存在依赖关系的。父模块中模块的配置顺序如下:
这里我们稍微做一下调整,用户管理模块可以提供接口给核心业务模块来调用,因此,在 mall-core 模块中引入 mall-account 依赖。重新进行项目构建。
从构建的结果来看,模块的构建顺序并不是按照我们在父模块中配置的顺序进行的,而是 Maven 在经过分析之后,生成反应堆,根据反应堆的构建顺序来进行构建的。
实际上,Maven 会根据模块间继承与依赖的关系来形成一个有向非循环图,并根据图中标记的顺序,来生成反应堆构建顺序,在构建的时候,根据这个顺序来进行构建。本节中的实例项目的有向非循环图如下:

继承与依赖关系的有向非循环图
在这个图中,是不能出现循环的,假如我们在 mall-account 模块中也添加入 mall-core 的依赖,再进行项目构建的时候,Maven 则会报错出来,提示我们这个反应堆中存在循环引用。
在本节的学习中,我们使用一个示例项目演示了 Maven 聚合与继承两个特性,以及两者之间的关系,最后介绍了 Maven 构建项目时候,反应堆构建顺序的生成,以及一些注意事项。
到此这篇swagger3使用(swagger3官网)的文章就介绍到这了,更多相关内容请继续浏览下面的相关推荐文章,希望大家都能在编程的领域有一番成就!版权声明:
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。
如若内容造成侵权、违法违规、事实不符,请将相关资料发送至xkadmin@xkablog.com进行投诉反馈,一经查实,立即处理!
转载请注明出处,原文链接:https://www.xkablog.com/rfx/41782.html