文章目录
前言
作为后端开放人员,最烦的事就是自己写接口文档和别人没有写接口文档,不管是前端还是后端开发,多多少少都会被接口文档所折磨,前端会抱怨后端没有及时更新接口文档,而后端又会觉得编写接口文档太过麻烦。Swagger 可以较好的接口接口文档的交互问题,以一套标准的规范定义接口以及相关的信息,就能做到生成各种格式的接口文档,生成多种语言和客户端和服务端的代码,以及在线接口调试页面等等。只需要更新 Swagger 描述文件,就能自动生成接口文档,做到前端、后端联调接口文档的及时性和便利性。
一、简介
Swagger 是一个规范且完整的框架,用于生成、描述、调用和可视化 RESTful 风格的 Web 服务。
Swagger 的目标是对 REST API 定义一个标准且和语言无关的接口,可以让人和计算机拥有无须访问源码、文档或网络流量监测就可以发现和理解服务的能力。当通过 Swagger 进行正确定义,用户可以理解远程服务并使用最少实现逻辑与远程服务进行交互。与为底层编程所实现的接口类似,Swagger 消除了调用服务时可能会有的猜测。
Swagger 的优势
- 支持 API 自动生成同步的在线文档:使用 Swagger 后可以直接通过代码生成文档,不再需要自己手动编写接口文档了,对程序员来说非常方便,可以节约写文档的时间去学习新技术。
- 提供 Web 页面在线测试 API:光有文档还不够,Swagger 生成的文档还支持在线测试。参数和格式都定好了,直接在界面上输入参数对应的值即可在线测试接口。
二、基本使用
1. 导入相关依赖
通过在项目中引入 Springfox,可以扫描相关的代码,生成该描述文件,进而生成与代码一致的接口文档和客户端代码。
<!-- swagger --><dependency><groupId>io.springfox</groupId><artifactId>springfox-spring-web</artifactId><version>2.9.2</version></dependency><dependency><groupId>io.springfox</groupId><artifactId>springfox-swagger2</artifactId><version>2.9.2</version></dependency><dependency><groupId>io.springfox</groupId><artifactId>springfox-swagger-ui</artifactId><version>2.9.2</version></dependency>
2. 编写配置文件
在配置文件
config
目录下,添加 swagger 的配置文件
SwaggerConfig.java
@Configuration// 配置类@EnableSwagger2// 开启 swagger2 的自动配置publicclassSwaggerConfig{}
这个时候 Swagger 已经算是整合到项目之中了,可以启动下服务,输入:
http://localhost:8080/swagger-ui.html#
(这里我的项目端口是 8868 ,项目路径是 /mike,所以我打开的文档地址为
http://localhost:8868/mike/swagger-ui.html#
)即可查看 swagger 文档。
可以看到 Swagger 文档中大概有这四类信息
- 组
- 基本信息
- 接口信息
- 实体类信息
2.1 配置基本信息
Swagger 有自己的实例 Docket,如果我们想要自定义基本信息,可以使用 docket 来配置 swagger 的基本信息,基本信息的设置在
ApiInfo
这个对象中。
Swagger 默认的基本信息展示
ApiInfo 中默认的基本设置
- title:Api Documentation
- description:Api Documentation
- version:1.0
- termsOfServiceUrl:urn:tos
- contact:无
- license:Apache 2.0
- licenseUrl:http://www.apache.org/licenses/LICENSE-2.0
SwaggerConfig.java
配置文件添加以下内容:
@BeanpublicDocketdocket(){// 创建一个 swagger 的 bean 实例returnnewDocket(DocumentationType.SWAGGER_2)// 配置基本信息.apiInfo(apiInfo());}// 基本信息设置privateApiInfoapiInfo(){Contact contact =newContact("米大傻",// 作者姓名"https://blog.csdn.net/xhmico?type=blog",// 作者网址"[email protected]");// 作者邮箱returnnewApiInfoBuilder().title("多加辣-接口文档")// 标题.description("众里寻他千百度,慕然回首那人却在灯火阑珊处")// 描述.termsOfServiceUrl("https://www.baidu.com")// 跳转连接.version("1.0")// 版本.license("Swagger-的使用(详细教程)").licenseUrl("https://blog.csdn.net/xhmico/article/details/125353535").contact(contact).build();}
重启服务,打开 Swagger 文档,基本信息改变如下所示:
2.2 配置接口信息
默认情况下,Swagger 是会展示所有的接口信息的,包括最基础的
basic-error
相关的接口
有时候我们希望不要展示
basic-error-controller
相关的接口,或者是说这想要显示某些接口,比如说:
user-controller
下的接口,由该怎么去实现呢?这个时候就需要设置
扫描接口
@BeanpublicDocketdocket(){// 创建一个 swagger 的 bean 实例returnnewDocket(DocumentationType.SWAGGER_2)// 配置接口信息.select()// 设置扫描接口// 配置如何扫描接口.apis(RequestHandlerSelectors//.any() // 扫描全部的接口,默认//.none() // 全部不扫描.basePackage("com.duojiala.mikeboot.controller")// 扫描指定包下的接口,最为常用//.withClassAnnotation(RestController.class) // 扫描带有指定注解的类下所有接口//.withMethodAnnotation(PostMapping.class) // 扫描带有只当注解的方法接口).paths(PathSelectors.any()// 满足条件的路径,该断言总为true//.none() // 不满足条件的路径,该断言总为false(可用于生成环境屏蔽 swagger)//.ant("/user/**") // 满足字符串表达式路径//.regex("") // 符合正则的路径).build();}
可根据自己的需求去设置对应的配置,这里我就不再一一赘述了,以上是我所设置的配置,重启服务,打开 Swagger 文档,接口信息改变如下所示:
可以看到之前
basic-error-controller
相关的接口已经没有了
2.3 配置分组信息
Swagger 默认只有一个 default 分组选项,如果没有设置,所有的接口都会显示在
default
`分组下,如果功能模块和接口数量一多,就会显得比较凌乱,不方便查找和使用。
swagger 文档中组名默认是
default
,可通过
.groupName(String )
@BeanpublicDocketdocket(){// 创建一个 swagger 的 bean 实例returnnewDocket(DocumentationType.SWAGGER_2).groupName("mike")// 修改组名为 "mike";}
修改后:
如果需要配置多个组的话,就需要配置多个
docket() 方法
,这里我就简单写两组,代码如下:
/**
* 展示 controller 包下所有的接口
*/@BeanpublicDocketdocket1(){// 创建一个 swagger 的 bean 实例returnnewDocket(DocumentationType.SWAGGER_2).groupName("mike")// 修改组名为 "mike"// 配置接口信息.select()// 设置扫描接口// 配置如何扫描接口.apis(RequestHandlerSelectors.basePackage("com.duojiala.mikeboot.controller")// 扫描指定包下的接口,最为常用).paths(PathSelectors.any()// 满足条件的路径,该断言总为true).build();}/**
* 展示路径为 /error 的所有接口(基础接口)
*/@BeanpublicDocketdocket2(){// 创建一个 swagger 的 bean 实例returnnewDocket(DocumentationType.SWAGGER_2).groupName("yank")// 修改组名为 "yank"// 配置接口信息.select()// 设置扫描接口// 配置如何扫描接口.apis(RequestHandlerSelectors.any()// 扫描全部的接口,默认).paths(PathSelectors.ant("/error")// 满足字符串表达式路径).build();}
重启服务,打开 Swagger 文档,接口信息改变如下所示:
组名为
mike
的文档中只有
user-controller
相关的接口信息
组名为
yank
的文档中只有
basic-error-controller
相关的接口信息
3. 控制 Swagger 的开启
在开发或者测试环境下,我们开启 swagger 会方便前端和后端的交互,但是如果在生产环境下也开启 swagger 的话,是会将接口暴露出去的,有极大风险,如何让 swagger 根据不同的环境来决定是否开启?
这里我准备了四个项目的配置文件,
dev
、
test
、
pro
三个环境的配置文件仅是端口上的不同
- application.yml -------------------------- 全局配置文件
- application-dev.yml -------------------- 开发环境配置文件
- application-test.yml -------------------- 测试环境配置文件
- application-pro.yml -------------------- 生产环境配置文件
application.yml
内容如下,用于指定选择的环境:
spring:profiles:active: dev
可以通过代码判断此时是在什么环境:
dev
、
test
、
pro
,如果是在
pro
生产环境,则关闭 swagger。
/**
* swagger 配置
* @param environment 环境
*/@BeanpublicDocketdocket(Environment environment){// 设置环境范围Profiles profiles =Profiles.of("dev","test");// 如果在该环境返回内则返回:true,反之返回 falseboolean flag = environment.acceptsProfiles(profiles);// 创建一个 swagger 的 bean 实例returnnewDocket(DocumentationType.SWAGGER_2).enable(flag)// 是否开启 swagger:true -> 开启,false -> 关闭;}
在
application.yml
全局配置文件中环境指向
dev
时,是可以打开 swagger 的
如果我将
application.yml
全局配置文件中环境指向
pro
时,就不能打开 swagger 了,提示
Could not render e, see the console
4. 常用注解使用
之前有说 Swagger 会将接口请求或者相应的实体类信息展示在
Models
下的,比如我
UserController.java
下有一个接口如下所示:
@PostMapping(value ="/query-user-info")publicResponseBeanqueryUserInfo(@RequestBody@ValidatedIdReq req){returnResponseBean.success(userService.queryUserInfo(req));}
它的请求体是
IdReq
,响应是
ResponseBean
,
Models
展示这两个实体类信息如下:
前端可通过看这个
Models
知道后端定义实体类的信息。
@ApiModel
该注解是作用于类上面的,是用来描述类的一些基本信息的。
相关属性:
value
:提供类的一个备用名,如果不设置,默认情况下将使用 class 类的名称- description:对于类,提供一个详细的描述信息
- parent:这个属性用于描述的是类的一些父类信息
- discriminator:这个属性解释起来比较麻烦,因为这个类主要体现在断言当中
- subTypes:可以通过这个属性,指定我们想要使用的子类
譬如:这个为给
IdReq
这个类添加该注解
@Data@NoArgsConstructor@AllArgsConstructor@ApiModel(value ="Id请求体")publicclassIdReq{privateString id;}
可以看到这里的名字从
IdReq
变成
Id请求体
了
@ApiModelProperty
它的作用是添加和操作属性模块的数据。
该注解的使用详情可参见博客:@ApiModelProperty注解的用法
这里我还是以
IdReq
类为例,为该类的属性添加说明
@Data@NoArgsConstructor@AllArgsConstructor@ApiModel(value ="Id请求体")publicclassIdReq{@ApiModelProperty("主键id")privateString id;}
可以看到这里对该字段有一个备注说明。
@ApiOperation
该注解用来对某个方法/接口进行描述
该注解的使用详情可参见博客:Swagger @ApiOperation 注解详解
这里我以
UserController
下的接口为例:
@PostMapping(value ="/query-user-info")@ApiOperation(value ="根据id查询用户详情")publicResponseBeanqueryUserInfo(@RequestBody@ValidatedIdReq req){returnResponseBean.success(userService.queryUserInfo(req));}
可以看见该接口就多了对其的描述信息。
@ApiParam
该注解使用在方法上或者参数上,字段说明,表示对参数的添加元数据(说明或者是否必填等)
相关属性:
- name:参数名
- value:参数说明
- required:是否必填
这里我以
UserController
下的接口为例:
@PostMapping(value ="/query-user-infos")@ApiOperation(value ="条件查询用户信息")publicResponseBeanqueryUserInfos(// name 用户名称 不必填@ApiParam(value ="用户名称", required =false)@RequestParam(required =false)String name,// gender 用户性别 必填@ApiParam(value ="用户性别", required =true)@RequestParam(required =true)GenderEnum gender
){returnResponseBean.success(userService.queryUserInfos(name,gender));}
这里会展示请求参数的备注信息,以及是否必填等。
5. 接口调用
使用 swagger 除了让前后端交互变得方便,也让接口的请求变得简单,只需要填写好请求所需要的参数信息,便可直接发起请求。
比如说接口
/user/query-user-info
点击
Try it out
设置好请求所需的参数,点击
Execute
执行
就能看到接口响应的结果了
接口
/user/query-user-infos
也差不多
三、进阶使用
1. 添加请求头
有时候我们的接口是需要获取请求头信息的,这样的话就还需要在 swagger 配置中添加请求头的配置。
@BeanpublicDocketdocket(){// 设置请求头List<Parameter> parameters =newArrayList<>();
parameters.add(newParameterBuilder().name("token")// 字段名.description("token")// 描述.modelRef(newModelRef("string"))// 数据类型.parameterType("header")// 参数类型.defaultValue("default value")// 默认值:可自己设置.hidden(true)// 是否隐藏.required(false)// 是否必须.build());// 创建一个 swagger 的 bean 实例returnnewDocket(DocumentationType.SWAGGER_2).groupName("mike")// 修改组名为 "mike"// 配置接口信息.select()// 设置扫描接口// 配置如何扫描接口.apis(RequestHandlerSelectors.basePackage("com.duojiala.mikeboot.controller")// 扫描指定包下的接口,最为常用).paths(PathSelectors.any()// 满足条件的路径,该断言总为true).build()// 添加请求头参数.globalOperationParameters(parameters);}
比如接口:
@GetMapping(value ="/get-token")@ApiOperation(value ="获取请求头中的token信息")publicvoidgetToken(@RequestHeader(value ="token",required =false)String token
){// 直接获取 token 信息System.out.println("token = "+ token);// 通过代码获取ServletRequestAttributes servletRequestAttributes =(ServletRequestAttributes)RequestContextHolder.getRequestAttributes();if(servletRequestAttributes !=null){HttpServletRequest request = servletRequestAttributes.getRequest();String header = request.getHeader("token");System.err.println("header = "+ header);}}
可以看到这个接口已经可以去设置请求头了,调用接口
后端也能获取到。
四、项目下载
以下是我这个项目所编写的代码
链接:百度网盘
提取码:na2o
相关博客:
SpringBoot - 快速搭建
版权归原作者 多加点辣也没关系 所有, 如有侵权,请联系我们删除。