Swagger
一、什么是swagger?
Swagger 是一个规范且完整的框架,用于生成、描述、调用和可视化 RESTful 风格的 Web 服务。Swagger 的目标是对 REST API 定义一个标准且和语言无关的接口,可以让人和计算机拥有无须访问源码、文档或网络流量监测就可以发现和理解服务的能力。用户可以理解远程服务并使用最少实现逻辑与远程服务进行交互
二、为什么要学习swagger?
首先肯定是因为用的人多,那为什么用的多呢?
故事要从前后端分离讲起啊!
-
前端 -> 前端控制层、视图层
-
后端 -> 后端控制层、服务层、数据访问层
-
前后端通过API进行交互
-
前后端相对独立且松耦合
在这个前后端分离的时代,产生了一个问题
- 前后端集成,前端或者后端无法做到“及时协商,尽早解决”,最终导致问题集中爆发
需要一个东西来解决这个问题
解决办法 - 实时跟踪最新的API,降低集成风险
作用:
-
接口的文档在线自动生成。
-
功能测试。
swagger官网点这里
三、swagger的优势
- swagger号称世界上最流行的api框架
- Restful Api文档在线自动生成工具=>api文档和api定义开发
- 直接运行,可以在线测试api接口;
- 执行多种语言(c#,java,php)
四、springboot集成swagger
1.新建springboot项目,导入依赖(这里提供三种方法)
(1)第一种导入ui和swagger2的包,目前最高为3.0但和高版本springboot不兼容出现各种问题不建议使用。其他版本可以使用
<!-- springfox-swagger-ui -->
<dependency>
<groupId>io.springfox</groupId>
<artifactId>springfox-swagger-ui</artifactId>
<version>2.9.2</version>
</dependency>
<!-- springfox-swagger2 -->
<dependency>
<groupId>io.springfox</groupId>
<artifactId>springfox-swagger2</artifactId>
<version>2.9.2</version>
</dependency>
(2)添加springfox官方Swagger依赖,兼容3.0.0版本
<dependency>
<groupId>io.springfox</groupId>
<artifactId>springfox-boot-starter</artifactId>
<version>3.0.0</version>
</dependency>
(3)swagger封装好了的 Starter 包
<!-- Swagger -->
<dependency>
<groupId>com.spring4all</groupId>
<artifactId>swagger-spring-boot-starter</artifactId>
<version>2.0.2.RELEASE</version>
</dependency>
进入源码中发现也是兼容3.0.0版本
2.编写HelloController确保项目可以跑起来
3.要使用Swagger,我们需要编写一个配置类SwaggerConfig来配置 Swagger
import org.springframework.context.annotation.Configuration;
import springfox.documentation.swagger2.annotations.EnableSwagger2;
@Configuration
@EnableSwagger2 // 开启Swagger2的自动配置
public class SwaggerConfig {
}
这里注意若swagger版本为3.0.0及以上不需要加@enableopenapi,和@enableswagger2这两个注解
4.测试访问
3.0.0及以上访问 http://localhost:8080/swagger-ui/
3.0.0以下访问 http://localhost:8080/swagger-ui.html
配置swagger
1、Swagger实例Bean是Docket,所以通过配置Docket实例来配置Swaggger。
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import springfox.documentation.spi.DocumentationType;
import springfox.documentation.spring.web.plugins.Docket;
import springfox.documentation.swagger2.annotations.EnableSwagger2;
@Configuration
@EnableSwagger2 // 开启Swagger2的自动配置
public class SwaggerConfig {
@Bean //配置docket以配置Swagger具体参数
public Docket docket() {
return new Docket(DocumentationType.SWAGGER_2);
}
}
2.可以通过apiInfo()属性配置文档信息,也就是这块
点进docket源码
发现有个默认点进去下翻
照猫画虎复制写自己的
private ApiInfo apiInfo(){
//作者信息
return new ApiInfo(
"swagger Study",// 标题
"Loving Study", // 描述
"100.0",// 版本
"urn:tos",// 组织链接
DEFAULT_CONTACT, // 联系人信息
"Apache 2.0", // 许可
"https://blog.youkuaiyun.com/m0_56183421?spm=1000.2115.3001.5343",// 许可连接
new ArrayList()// 扩展
);
}
这里直接粘过来DEFAULT_CONTACT会报错需要添加DEFAULT_CONTACT
Contact DEFAULT_CONTACT = new Contact("联系人名字", "http://xxx.xxx.com/联系人访问链接", "联系人邮箱");
这里三个字符串也可为空
Contact DEFAULT_CONTACT = new Contact(“”, “”, “”);
3.Docket 实例关联上 apiInfo()
@Bean
public Docket docket() {
return new Docket(DocumentationType.SWAGGER_2).apiInfo(apiInfo());
}
4.重启项目,访问测试 http://localhost:8080/swagger-ui.html (3.0.0以下)或http://localhost:8080/swagger-ui/(3.0.0) 看下效果;
配置扫描接口
1.通过.select()方法,去配置扫描接口
需要.build()不报错,这里涉及设计模式中的建造者模式了,build什么呢?
apis
需要RequestHandler是接口使用它的实现类RequestHandlerSelectors
//扫描方法上的注解 withMethodAnnotation
.apis(RequestHandlerSelectors.withMethodAnnotation(GetMapping.class))//只扫描get请求
//扫描类上的注解 withClassAnnotation
.apis(RequestHandlerSelectors.withClassAnnotation(RestController.class))//只扫描有RestController注解的类中的接口
//扫描全部
.apis(RequestHandlerSelectors.any())
包扫描:
.select()
//指定我们基于什么包扫描
.apis(RequestHandlerSelectors.basePackage("com.test.controller"))
.build();
这里注意一旦自定义了,swagger只会扫描你指定的而不会扫描其他的(这里只扫描了controller包下的)
2.配置扫描过滤
//配置允许扫描的路径(这里是所有都可)"/test/**"就是/test开头的请求
.paths(PathSelectors.ant("/**"))
可选值还有
any() // 任何请求都扫描
none() // 任何请求都不扫描
regex(final String pathRegex) // 通过正则表达式控制
ant(final String antPattern) // 通过ant()控制
配置Swagger开关
通过enable()方法配置是否启用swagger,如果是false,swagger将不能在浏览器中访问了
这里注意.enable()的位置
这里会出现一道题,怎么实现在test、dev环境时开启swagger而prod环境时关闭swagger,因为为了安全正式发布时要关闭swagger!!!
总结了两种方法
首先创建三个properties或者yaml,如图
设置端口号分别为8080,8081,8082
@Bean
public Docket docket(Environment environment) {
Profiles profiles = Profiles.of("dev","test");
boolean flag = environment.acceptsProfiles(profiles);
return new Docket(DocumentationType.SWAGGER_2).apiInfo(apiInfo())
.enable(flag)
.select()
.apis(RequestHandlerSelectors.basePackage("com.test.controller"))
.paths(PathSelectors.ant("/**"))
.build();
}
@Autowired
private ApplicationContext context;
boolean flag = false;
@Bean
public Docket docket() {
String[] profiles = context.getEnvironment().getActiveProfiles();
for (String profile : profiles) {
System.out.println(profile);
flag = profile.equals("dev");
}
return new Docket(DocumentationType.SWAGGER_2).apiInfo(apiInfo())
.enable(flag)
.select()
.apis(RequestHandlerSelectors.basePackage("com.test.controller"))
.paths(PathSelectors.ant("/**"))
.build();
}
配置API分组
没有配置分组默认是default
通过groupName()方法即可设置组的名称
如何配置多个分组?配置多个分组只需要配置多个docket即可:
@Bean
public Docket docket(Environment environment) {
Profiles profiles = Profiles.of("dev","test");
boolean flag = environment.acceptsProfiles(profiles);
return new Docket(DocumentationType.SWAGGER_2).apiInfo(apiInfo())
.groupName("hlb")
.enable(flag)
.select()
.apis(RequestHandlerSelectors.basePackage("com.test.controller"))
.paths(PathSelectors.ant("/**"))
.build();
}
@Bean
public Docket docket1(Environment environment){
return new Docket(DocumentationType.SWAGGER_2)
.apiInfo(apiInfo())
.groupName("swagger1");
}
@Bean
public Docket docket2(Environment environment){
return new Docket(DocumentationType.SWAGGER_2)
.apiInfo(apiInfo())
.groupName("swagger2");
}
效果
如果没有设置,所有的接口都会显示在 default 分组下,如果功能模块和接口数量一多,就会显得有些凌乱,不方便查找和使用。
实体配置
1.新建一个实体类(注意这里使用public,因为private扫描不到需要提供get和set方法)
public class User {
public String username;
public String password;
}
2.只有这个实体在请求接口的返回值上(即使是泛型),才能映射到swagger中
//编写请求
@PostMapping("/user")
public User user(){
return new User();
}
注释在实体类上的swagger注解:
@ApiModel(“用户实体类”) //解释类是干什么的,用在类上
@ApiModelProperty(“用户名”) //解释字段的,用在字段上
@ApiModel("用户实体类")
public class User {
@ApiModelProperty("用户名")
public String username;
@ApiModelProperty("密码")
public String password;
}
效果图:
注:并不是因为@ApiModel这个注解让实体显示在这里了,而是只要出现在接口方法的返回值上的实体都会显示在这里,而@ApiModel和@ApiModelProperty这两个注解只是为实体添加注释的。
常用注解
Swagger的所有注解定义在io.swagger.annotations包下
Swagger注解 | 说明 |
---|---|
@Api(tags = “xxx模块说明”) | 作用在controller类上 |
Swagger注解 | 说明 |
---|---|
@ApiOperation(“xxx接口说明”) | 作用在接口方法上 |
@ApiParam(“xxx参数说明”) | 作用在参数、方法和字段上,类似@ApiModelProperty |
这样的话,可以给一些比较难理解的属性或者接口,增加一些配置信息,让人更容易阅读!
五、swagger接口测试
可以测试自己的接口是否有效
@ApiOperation("postt")
@PostMapping("/postt")
public User hello2(@ApiParam("hhh") User user){
return user;
}
测试
成功响应
若有错误呢?我们故意加点错测试一下
发现错误很明显的被指出来了!
总结:swagger是个优秀的工具值得学习!!!