前言
接口文档对于前后端开发人员都十分重要。尤其近几年流行前后端分离后接口文档又变
成重中之重。接口文档固然重要,但是由于项目周期等原因后端人员经常出现无法及时更新,
导致前端人员抱怨接口文档和实际情况不一致。
很多人员会抱怨别人写的接口文档不规范,不及时更新。但是当自己写的时候确实最烦
去写接口文档。这种痛苦只有亲身经历才会牢记于心。
如果接口文档可以实时动态生成就不会出现上面问题。
Swagger可以完美的解决上面的问题。
Open API 是什么
Open API规范(OpenAPI Specification)以前叫做 Swagger 规范,是 REST API 的API
描述格式。
Open API 文件允许描述整个API,包括︰
● 每个访问地址的类型。POST 或 GET。I
● 每个操作的参数。包括输入输出参数。
● 认证方法。
● 连接信息,声明,使用团队和其他信息。
Open API 规范可以使用 YAML 或 JSON 格式进行编写。这样更利于我们和机器进行
阅读。
OpenAPI规范 (OAS ) 为 REST API 定义了一个与语言无关的标准接口,允许人和计
算机发现和理解服务的功能,而无需访问源代码,文档或通过网络流量检查。正确定义后,
消费者可以使用最少量的实现逻辑来理解远程服务并与之交互。
然后,文档生成工具可以使用 OpenAPI 定义来显示 API ,使用各种编程语言生成服务
器和客户端的代码生成工具,测试工具以及许多其他用例。
个人理解:Swagger 可以自动的将代码转换成 YAML 或 JSON 格式的接口文档,确保接口文档的实时更新,并且减少写接口文档的痛苦。
swagger 的使用
在中心仓库搜索 springfox-swagger2,直接使用 swagger 不方便,springfox 对 swagger 进行了封装,可以更方便的使用。
链接:https://mvnrepository.com/artifact/io.springfox/springfox-swagger2
向 Spring 项目中添加 springfox-swagger2 的依赖:
<!-- https://mvnrepository.com/artifact/io.springfox/springfox-swagger2 -->
<dependency><groupId>io.springfox</groupId><artifactId>springfox-swagger2</artifactId><version>3.0.0</version>
</dependency>
再向项目中添加视图逻辑,这样才可以生成方便查看的接口文档。
在中心仓库搜索 springfox-swagger-ui
链接:https://mvnrepository.com/artifact/io.springfox/springfox-swagger-ui
向 Spring 项目中添加 springfox-swagger-ui 的依赖:
<!-- https://mvnrepository.com/artifact/io.springfox/springfox-swagger-ui -->
<dependency><groupId>io.springfox</groupId><artifactId>springfox-swagger-ui</artifactId><version>3.0.0</version>
</dependency>
@EnableSwagger2
@EnableSwagger2 是 springfox 提供的一个注解,代表 swagger2 相关技术开启。 加上该注解后会扫描当前类所在包,以及子包中所有类的注解,做 swagger 文档的定值,一般加在启动类上
/*** @EnableSwagger2 是 springfox 提供的一个注解,代表 swagger2 相关技术开启。* 会扫描当前类所在包,以及子包中所有类的注解,做 swagger 文档的定值* */
@SpringBootApplication
@EnableSwagger2
public class SwaggerApplication {public static void main(String[] args) {SpringApplication.run(SwaggerApplication.class, args);}
}
一般情况下加上 @EnableSwagger2 后就可以直接访问 http://localhost:8080/swagger-ui.html 查看 swagger ui 的界面了
但是博主遇到了两个问题,一个是直接报错无法运行,一个是 查看 swagger ui 的界面是 404
错误
直接报错无法运行
此时博主直接尝试运行遇到了一个错误
这个问题通常发生在 Spring Boot 2.6 及以上版本中,当整合 Swagger 时,由于Spring MVC的路径匹配策略变更导致的兼容性问题。在Spring Boot 2.6版本之后,默认的路径匹配策略由AntPathMatcher
改为了 PathPatternParser
,而Swagger(Springfox)仍然使用AntPathMatcher
,这就导致了冲突。
我通过下面的办法解决了问题:
修改路径匹配策略:在 application.properties
或 application.yml
配置文件中,添加以下配置来指定使用 AntPathMatcher
作为路径匹配策略:
spring.mvc.pathmatch.matching-strategy=ant_path_matcher
查看 swagger ui 的界面是 404
我们需要创建一个 SwaggerConfig 配置类,在配置类中添加如下配置:
package com.example.swagger.config;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import springfox.documentation.builders.ApiInfoBuilder;
import springfox.documentation.builders.PathSelectors;
import springfox.documentation.builders.RequestHandlerSelectors;
import springfox.documentation.service.ApiInfo;
import springfox.documentation.spi.DocumentationType;
import springfox.documentation.spring.web.plugins.Docket;
import springfox.documentation.swagger2.annotations.EnableSwagger2;/*** @author 全栈学习笔记* @date 2020/4/19 16:00* @description*/
@Configuration
@EnableSwagger2
public class SwaggerConfig {@Beanpublic Docket createRestApi() {return new Docket(DocumentationType.SWAGGER_2)// 指定构建api文档的详细信息的方法:apiInfo().apiInfo(apiInfo()).select()// 指定要生成api接口的包路径.apis(RequestHandlerSelectors.basePackage("com.example.swagger.controller"))//使用了 @ApiOperation 注解的方法生成api接口文档//.apis(RequestHandlerSelectors.withMethodAnnotation(ApiOperation.class)).paths(PathSelectors.any())//可以根据url路径设置哪些请求加入文档,忽略哪些请求.build();}/*** 设置api文档的详细信息*/private ApiInfo apiInfo() {return new ApiInfoBuilder()// 标题.title("Spring Boot集成Swagger2")// 接口描述.description("swagger")// 版本信息.version("1.0")// 构建.build();}
}
就可以正常访问到我们的 swagger ui 界面了
使用 swagger ui 检查接口是否正确
首先我们先写一些接口类:
@RestController
public class MyController {@GetMapping("/get")public String get(String id){return "get";}@PostMapping("/post")public String post(String id,String name){return "post";}@RequestMapping("/req")public String req(){return "req";}
}
注意:要在 SwaggerConfig 配置类中加上 MyController 类的包名
再次访问 swagger ui 界面可以看到已经有了接口信息
点击一个接口我们可以看到该接口的详细信息,点击 Try it out 可以发起请求检测接口的返回信息
在方框中输入要传递的参数值 id=1
点击 Execute 发送请求
在下面的信息栏就可以查看接口返回的信息,判断接口是否正常工作
swagger 常用注解
@Api 描述类
用于描述当前类型生成帮助文档的信息(该注解只能用于类上)
属性:
tags :给当前类型定义别名,可以定义多个。定义几个别名,就在 ui 视图中显示几个控制器访问菜单。
description :给当前类型生成的帮助文档定义一个描述信息(已经过时了)
@RestController
@RequestMapping("/MyController")
/*** @Api - 描述当前类型生成帮助文档的信息* 属性-* - tags :给当前类型定义别名,可以定义多个。定义几个别名,就在 ui 视图中显示几个控制器访问菜单。* - description :给当前类型生成的帮助文档定义一个描述信息(已经过时了)* */
@Api(tags = {"MyController","swagger学习控制器"},description = "测试 api 信息")
public class MyController {@GetMapping("/get")public String get(String id){return "get";}@PostMapping("/post")public String post(String id,String name){return "post";}@RequestMapping("/req")public String req(){return "req";}
}
可以看到给 MyController 类设置别名后出现了一个新的控制器访问菜单
@ApiOperation 描述方法
用于描述方法的信息(该注解可以用于类上和方法上,但通常用于方法上)
属性:
value:对方法的描述信息
notes:对方法的提示信息 (两个属性的信息所在位置不同)
@RestController
@RequestMapping("/MyController")@Api(tags = {"MyController","swagger学习控制器"},description = "测试 api 信息")
public class MyController {@ApiOperation(value = "get方法,获取客户 id ",notes = "swagger 学习使用 - 处理 GET 请求的方法")@GetMapping("/get")public String get(String id){return "get";}@PostMapping("/post")public String post(String id,String name){return "post";}@RequestMapping("/req")public String req(){return "req";}
}
如下图,get 方法后有描述信息,post 方法后没有描述信息
点开接口详情,可以看到对该接口的提示信息
@ApiParam 描述参数
用于描述参数的信息
属性:
name:参数名称
value:对参数的描述信息
required:该参数是否必须(默认是 false)
@RestController
@RequestMapping("/MyController")@Api(tags = {"MyController","swagger学习控制器"},description = "测试 api 信息")
public class MyController {@ApiOperation(value = "get方法,获取客户 id ",notes = "swagger 学习使用 - 处理 GET 请求的方法")@GetMapping("/get")public String get(String id){return "get";}@PostMapping("/post")public String post(@ApiParam(name = "用户 id ",value = "新增用户时用的用户 id ",required = true) String id,@ApiParam(name = "用户名",value = "新增用户时用的用户名",required = true) String name){return "post";}@RequestMapping("/req")public String req(){return "req";}
}
可以看到属性有了详细的描述信息
@ApiIgnore 忽略
忽略该注解描述的方法和类,不生产 api 帮助文档
// @ApiIgnore - 忽略该注解描述的方法和类,不生成 api 帮助文档@ApiIgnore@RequestMapping("/req")public String req(){return "req";}
如同,添加后由 RequestMapping 产生的多个接口的文档都消失了
@ApiImplicitParams 在方法前描述参数
在方法前描述参数。
属性:
name:参数名称
value:对参数的描述信息
required:该参数是否必须(默认是 false)
paramType:该参数的类型
@RestController
@RequestMapping("/MyController")@Api(tags = {"MyController","swagger学习控制器"},description = "测试 api 信息")
public class MyController {@ApiOperation(value = "get方法,获取客户 id ",notes = "swagger 学习使用 - 处理 GET 请求的方法")@GetMapping("/get")@ApiImplicitParams(value = {@ApiImplicitParam(name = "id",value = "前端获取用户id",paramType = "int",required = true),@ApiImplicitParam(name = "name",value = "前端获取用户名",paramType = "字符串")})public String get(String id,String name){return "get";}@PostMapping("/post")public String post(@ApiParam(name = "用户 id ",value = "新增用户时用的用户 id ",required = true) String id,@ApiParam(name = "用户名",value = "新增用户时用的用户名",required = true) String name){return "post";}// @ApiIgnore - 忽略该注解描述的方法和类,不生成 api 帮助文档@ApiIgnore@RequestMapping("/req")public String req(){return "req";}
}
作用和 @ApiParam 相同,只是写在方法上而已
@ApiModel 与 @ApiModelProperty 描述实体类型
@ApiModel 与 @ApiModelProperty 描述实体类型,这个实体类型如果成为了接口的返回类型并且该接口生成了接口文档,那么此注解会被解析,生成描述实体类型的文档
@ApiModel(value = "学生实体 - Student ",description = "存储学生信息")
public class Student{@ApiModelProperty(value = "主键",name = "主键(id)",required = true,example = "q",hidden = false)private String id; //主键@ApiModelProperty(value = "姓名",name = "姓名(name)",required = true,example = "张三",hidden = false)private String name; //姓名@ApiModelProperty(value = "密码",name = "密码(password)",required = true,example = "123456",hidden = false)private String password; //密码public Student(){};public String getId() {return id;}public void setId(String id) {this.id = id;}public String getName() {return name;}public void setName(String name) {this.name = name;}public String getPassword() {return password;}public void setPassword(String password) {this.password = password;}
}
@GetMapping("/getStudentInfo")public Student getStudentInfo(){return new Student();}
如图,可以查看实体的详细信息
@ApiModel
描述实体类
属性:
value:该实体的名称
description:该实体的描述
@ApiModelProperty
描述实体类的属性
属性:
name:属性的名称
value:属性的描述
required:是否必须
example:示例
hidden:是否隐藏