学习目标;
1)了解Swagger的作用和概念;
2)了解前后端分离;
3)在SpringBoot中集成Swagger;
一)Swagger简介:
1)Swagger™的目标是为REST APIs 定义一个标准的,与语言无关的接口,使人和计算机在看不到源码或者看不到文档或者不能通过网络流量检测的情况下能发现和理解各种服务的功能。当服务通过Swagger定义,消费者就能与远程的服务互动通过少量的实现逻辑。类似于低级编程接口,Swagger去掉了调用服务时的很多猜测。
2)产生原因(趋势):
越来越多的大公司趋向于前后端分离,可以提高工作效率,慢慢的进入前后端分离时代;
现在主流的是Vue + SpringBoot进行开发;
后端时代:前端只需要负责管理静态页面,后端页面主要是通过html,模板引擎,jsp页面生成的;
二)前后端分离时代:
后端负责控制层,服务层,数据访问层;
前端负责控制层和视图层,他们可以通过伪造后端json数据,不需要后端,前端工程也依旧可以跑起来;
前后端交互的话可以通过API来进行,前后端项目的话甚至可以部署在不同的服务器上;
这样,就会产生一个问题:
前后端集成联调,前端人员和后端人员无法做到“及时协商,尽早解决”,最终导致问题集中爆发;
通常的解决方案是:
1)首先指定schema【计划的提纲】,实时更新最新的API,降低集成的风险;
2)早些年的时候,还会制定word计划文档;
3)前后端分离时代:
前端测试后端接口:postman;后端提供接口,需要实时更新最新的消息及改动;
慢慢的,swagger就孕育而生了。
Swagger:
号称世界上最流行的Api框架,RestFul Api文档在线自动生成工具(Api文档与API定义同步更新),而且,启动项目直接运行就可以了。
三)SpringBoot集成Swagger;
1)新建一个SpringBoot项目;
2)导入相关依赖3.0.0版本(3..0.0以下版本的依赖有所不同,具体看我上一篇文章有说明,这里不再阐述)
<!-- https://mvnrepository.com/artifact/io.springfox/springfox-boot-starter-->
<dependency>
<groupId>io.springfox</groupId>
<artifactId>springfox-boot-starter</artifactId>
<version>3.0.0</version>
</dependency>
3)编写一个index工程;
4)配置Swagger,这里需要写一个Config配置文件;
@Configuration //@EnableSwagger2 //开启Swagger2,这是3.0.0以下版本的注解 @EnableOpenApi //这是3.0.0版本的注解 public class SwaggerConfig { }
5)测试运行:http://localhost:8083/swagger-ui/index.html#
页面如下图所示:
配置Swagger:
1)Swagger的bean实例Docket;
//配置了Swagger的Docker的bean实例 @Bean public Docket docket(Environment environment){ return new Docket(DocumentationType.SWAGGER_2) .apiInfo(apiInfo()) .enable(true)//enable是否启动swagger,如果为false,则swagger不能在浏览器中访问 .select() //RequestHandlerSelectors:配置要扫描接口的方式 //basePackage:指定要扫描的包 //any():扫描全部 //none():不扫描 //withClassAnnotation:扫描类上的注解,参数是一个注解的反射对象 //withMethodAnnotation:扫描方法上的注解 .apis(RequestHandlerSelectors.basePackage("com.example.swagger.controller")) //paths(). 过滤什么路径 .paths(PathSelectors.ant("/kuang/**")) .build(); }
这里插播一个常见面试问题;
如果我值希望我的Swagger在生产环境中使用,在发布的时候不使用呢;
思路:判断是不是生产环境(flag=false),再注入enable(flag);
创建两个配置文件,一个是dev,一个pro,分别设置其相应的端口号;
@Configuration //@EnableSwagger2 //开启Swagger2 @EnableOpenApi public class SwaggerConfig { //配置了Swagger的Docker的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()) .enable(flag)//enable是否启动swagger,如果为false,则swagger不能在浏览器中访问 .select() //RequestHandlerSelectors:配置要扫描接口的方式 //basePackage:指定要扫描的包 //any():扫描全部 //none():不扫描 //withClassAnnotation:扫描类上的注解,参数是一个注解的反射对象 //withMethodAnnotation:扫描方法上的注解 .apis(RequestHandlerSelectors.basePackage("com.example.swagger.controller")) //paths(). 过滤什么路径 .paths(PathSelectors.ant("/kuang/**")) .build(); } }
2)配置API文档的分组 = >创建多个Docket实例即可;
.groupName("name");
@Configuration //@EnableSwagger2 //开启Swagger2 @EnableOpenApi public class SwaggerConfig { //配置多个Bean @Bean public Docket docket1(){ return new Docket(DocumentationType.SWAGGER_2).groupName("A"); } @Bean public Docket docket2(){ return new Docket(DocumentationType.SWAGGER_2).groupName("B"); } @Bean public Docket docket3(){ return new Docket(DocumentationType.SWAGGER_2).groupName("C"); } //配置了Swagger的Docker的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()) .enable(flag)//enable是否启动swagger,如果为false,则swagger不能在浏览器中访问 .select() //RequestHandlerSelectors:配置要扫描接口的方式 //basePackage:指定要扫描的包 //any():扫描全部 //none():不扫描 //withClassAnnotation:扫描类上的注解,参数是一个注解的反射对象 //withMethodAnnotation:扫描方法上的注解 .apis(RequestHandlerSelectors.basePackage("com.example.swagger.controller")) //paths(). 过滤什么路径 .paths(PathSelectors.ant("/kuang/**")) .build(); } }
效果如下图所示:
3)swagger常用注解;
//@Api("注释") @ApiModel("用户实体类") //给生成的文档加注释 public class User { //注意,这里实体类的属性不能是private的,私有属性不会被暴露和注释 @ApiModelProperty("用户名") public String username; @ApiModelProperty("密码") public String password; }
@ApiOperation("Hello控制类")//Operation接口,不是放在类上,是方法上 @GetMapping(value = "/hello") public String hello(@ApiParam("用户名") String username){ return "hello"+username; }
@ApiOperation("Post测试类")
@GetMapping(value = "/postTest")
public User postTest(@ApiParam("用户") User user){
int i = 5/0;
return user;
}
@ApiModel("用户实体类"):用在类上解释说明;
@ApiModelProperty("用户名"):用在属性上解释说明;
@ApiOperation("Hello控制类"):用在方法上解释说明;
@ApiParam("用户"):用在参数上解释说明;
4)总结:
1、我们可以通过Swagger给一些比较难理解的属性或接口,增加注释信息;
2、接口文档实时更新,提高开发效率;
3、可以在线测试;
总之,Swagger是一个优秀的工具,几乎很多大公司都使用它,需要注意的是,在正式发布的时候,需要关闭Swagger,出于安全考虑,而且节省运行的内存。