查看swagger教学视频,请点击 《狂神说java》: https://www.bilibili.com/video/BV1Y441197Lw?p=1 记得投币三连呀~~
Swagger
学习目标:
- 了解Swagger的作用和概念
- 了解前后端分离
- 在SpringBoot中继承Swagger
Swagger简介
前后端分离
Vue + SpringBoot
后端时代:
前端只用管理静态页面(html),再交给后端。后端通过模板引擎(如jsp)将页面重构,后端是主力!
前后端分离时代:
-
后端:后端控制层,服务层,数据访问层 【后端团队】
-
前端:前端控制层,视图层 【前端团队】
- 伪造后端数据,json。数据已经存在了,不需要后端,前端工程依旧可以跑起来。
-
前后端如何交互?===> API
-
前后端相对独立,松耦合;
-
前后端甚至可以部署在不同服务器上。
产生一个问题:
-
前后端集成联调,前端人员和后端人员无法做到“及时协商,尽早解决”,最终导致问题集中爆发;
-
首先指定schema,实时更新API,降低集成风险;
-
早些年:指定word计划文档;
-
前后端分离:
- 前端测试后端接口使用:postman
- 后端提供接口,需要实时更新最新的消息及改动!
Swagger
-
号称世界上最流行的API框架
-
Restful API文档在线自动生成工具=> API文档与API定义同步更新
-
直接运行,可以在线测试API接口;
-
支持多种语言:(java、php...)
在项目中使用Swagger需要springfox:
- swagger2
- ui
SpringBoot集成Swagger
目录结构:
1、新建springboot项目
2、导入依赖
<!-- https://mvnrepository.com/artifact/io.springfox/springfox-swagger2 -->
<dependency>
<groupId>io.springfox</groupId>
<artifactId>springfox-swagger2</artifactId>
<version>2.9.2</version>
</dependency>
<!-- https://mvnrepository.com/artifact/io.springfox/springfox-swagger-ui -->
<dependency>
<groupId>io.springfox</groupId>
<artifactId>springfox-swagger-ui</artifactId>
<version>2.9.2</version>
</dependency>
3、编写helloworld
4、配置Swagger===>Config
@Configuration
@EnableSwagger2 //开启swagger2
public class SwaggerConfig {
}
5、测试运行:http://localhost:8080/swagger-ui.html
配置Swagger
配置了Swagger的docket的bean实例
@Configuration
@EnableSwagger2 //开启swagger2
public class SwaggerConfig {
//配置了swagger的docket的bean实例
@Bean
public Docket docket(){
return new Docket(DocumentationType.SWAGGER_2)
.apiInfo(apiInfo());
}
配置swagger的信息
//配置swagger信息ApiInfo
private ApiInfo apiInfo(){
//作者信息
Contact CONTACT = new Contact("ztx", "https://www.cnblogs.com/", "123445@qq.com");
//要返回的swagger信息=apiInfo
return new ApiInfo("小帅哥的swaggerAPI文档",
"这个帅哥确实帅",
"1.0",
"https://www.bilibili.com/video/BV1Y441197Lw?p=2",
CONTACT,
"Apache 2.0",
"http://www.apache.org/licenses/LICENSE-2.0",
new ArrayList());
}
}
之前的swagger信息是默认的,以上代码是我们对swagger信息的重新定义!
自定义后的swagger信息,如下:
Swagger配置扫描接口
Docket.select
用法: .select() + ( .apis(xxx) / .path(xxx) ) + .build() 必须要和 .build() 方法搭配使用!!!
//配置了swagger的docket的bean实例
@Bean
public Docket docket(){
return new Docket(DocumentationType.SWAGGER_2)
.apiInfo(apiInfo())
.select()
//RequestHandlerSelectors,配置要扫描接口的方式
//basePackage():指定要扫描的包
//.basePackage("com.ztx.swagger.controller")
//withClassAnnotation():扫描类上的注解,参数是一个注解的反射对象
//.withClassAnnotation(RestController.class)
//withMethodAnnotation():扫描方法上的注解
//.withMethodAnnotation(RequestMapping.class)
//any():扫描全部,无参数
//none():不扫描,无参数
.apis(RequestHandlerSelectors.basePackage("com.ztx.swagger.controller"))
//path():过滤什么路径
//.paths(PathSelectors.ant("/ztx/**"))
.build();
}
因为在配置扫描接口方式时,我们定义的是只扫描"com.ztx.swagger.controller"包下面的,所以页面中接口信息部分如下:
配置是否开启Swagger
@Bean
public Docket docket(){
return new Docket(DocumentationType.SWAGGER_2)
.apiInfo(apiInfo())
//enable:是否开启swagger,如果为false,则swagger不开启,不能在浏览器中访问到swagger页面
.enable(false)
.select()
.apis(RequestHandlerSelectors.basePackage("com.ztx.swagger.controller"))
.build();
}
浏览器中访问不到swagger页面
问题:如何做到我只希望我的swagger在生产环境中使用,在发布时不使用?
- 判断是不是生产环境 flag = false or flag = true
- 注入enable(flag)
当前项目环境设为: 开发环境 !
设置开发环境和生产环境服务器端口号!
判断当前环境是否开发环境,从而决定是否开启swagger!
@Bean //获取当前环境需要用到environment对象
public Docket docket(Environment environment){
//设置要显示的Swagger环境,是否处于dev或test环境
Profiles profiles = Profiles.of("dev","test");
//通过environment.acceptsProfiles判断是否处在自己设定的环境当中
boolean flag = environment.acceptsProfiles(profiles);
return new Docket(DocumentationType.SWAGGER_2)
.apiInfo(apiInfo())
//是否开启swagger
.enable(flag)
.select()
.apis(RequestHandlerSelectors.basePackage("com.ztx.swagger.controller"))
.build();
}
可以发现swagger页面只有在开发环境下的8081端口才可以显示,在生产环境的8082端口无效:
配置swaggerAPI文档分组
当多人协作开发时,每个人负责各自不同的业务区,这时为了便于显示每个人的业务是否合规,就需要用到分组功能,一个docket对应一个人:
@Bean
public Docket docket1(){
return new Docket(DocumentationType.SWAGGER_2)
.apiInfo(apiInfo())
.groupName("李华")
。。。。。
.enable(false);
}
@Bean
public Docket docket2(){
return new Docket(DocumentationType.SWAGGER_2)
.apiInfo(apiInfo())
.groupName("旺仔")
。。。。。
.enable(true);
}
//配置了swagger的docket的bean实例
@Bean
public Docket docket(Environment environment){
//设置要显示的Swagger环境
Profiles profiles = Profiles.of("dev","test");
//通过environment.acceptsProfiles判断是否处在自己设定的环境当中
boolean flag = environment.acceptsProfiles(profiles);
return new Docket(DocumentationType.SWAGGER_2)
.apiInfo(apiInfo())
.groupName("狂神")
.enable(flag)
.select()
.apis(RequestHandlerSelectors.basePackage("com.ztx.swagger.controller"))
.build();
}
前端页面展示:(可以看到有三个定义的组,且每个组对应的swagger页面内容也是不同的)
配置文档注释
创建一个实体类User:
public class User {
public String username;
public String password;
}
在controller中添加如下方法:
//只要我们的接口中,返回值中存在实体类,它就会被扫描到swagger中
@PostMapping("/user")
public User user(){
return new User();
在User实体类添加Api相关注解:
@ApiModel("用户实体类")
public class User {
@ApiModelProperty("用户名")
public String username;
@ApiModelProperty("密码")
public String password;
}
加与没加Api注解的对比,如下图:
发现@Api注解 主要起到注释的作用!
在HelloController下使用Api注解:
@RestController
public class HelloController {
@GetMapping("/hello")
public String hello(){
return "hello";
}
//只要我们的接口中,返回值中存在实体类,它就会被扫描到swagger中
@PostMapping("/user")
public User user(){
return new User();
}
//Operation接口,不是放在类上,是方法上
@ApiOperation("这是一个hello2方法")
@GetMapping("/hello2")
public String hello2(@ApiParam("用户名") String username){
return "hello2"+username;
}
}
前端页面显示:发现使用api注解的地方都出现了注释!!!
补充一点:
@Api(tags = "hello控制器") //添加在类上,该控制器注释同样会出现在页面文档中,由于该处是后加的,故上面截图就没体现出来
@RestController
public class HelloController {....}
常用注解
Swagger的所有注解定义在io.swagger.annotations包下
下面列一些经常用到的,未列举出来的可以另行查阅说明:
Swagger注解 | 简单说明 |
---|---|
@Api(tags = "xxx模块说明") | 作用在模块类上 |
@ApiOperation("xxx接口说明") | 作用在接口方法上 |
@ApiModel("xxxPOJO说明") | 作用在模型类上:如VO、BO |
@ApiModelProperty(value = "xxx属性说明",hidden = true) | 作用在类方法和属性上,hidden设置为true可以隐藏该属性 |
@ApiParam("xxx参数说明") | 作用在参数、方法和字段上,类似@ApiModelProperty |
总结
- 我们可以通过swagger给一些比较难理解的属性或者接口,增加注释信息
- 接口文档实时更新
- 可以在线测试