背景
在前后端分离开发的时代,前端和后端的实时交互(后端接口改变前端可以及时看到),成为了一个主要问题之一,前后端沟通成本越来越高,前后端人员无法做到“即时协商”,最终导致问题爆发
以前的解决方案:
- 指定schema【计划提纲】,实时更新最新的API,降低集成的风险
- 制定word计划文档
- 前后端分离:
- 前端测试后端接口,工具:postman
- 后端提供接口,需要实时更新最新的消息及改动
简介
- 号称世界上最流行的API框架
- 是一套开源的框架
- RestFul Api文档在线自动生成工具 >>> Api文档与Api定义同步更新
- 直接运行,可以在线测试Api接口
- 支持多种语言
官网:https://swagger.io/
SpringBoot集成Swagger
需要的两个依赖:
新建一个SpringBoot-Web项目,并导入相关依赖
<dependencies>
<!-- 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>
编写一个Hello工程
/**
* @Author 凉白开_LBK
* @Date 2021/10/25 10:08
* @Explain
*/
@RestController
public class HelloController {
@RequestMapping("/HelloWorld")
public String hello(){
return "hello,world";
}
}
配置SwaggerConfig
测试运行:http://localhost:8080/swagger-ui.html
配置Swagger
package com.lbk.swagger.config;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import springfox.documentation.service.ApiInfo;
import springfox.documentation.service.Contact;
import springfox.documentation.spi.DocumentationType;
import springfox.documentation.spring.web.plugins.Docket;
import springfox.documentation.swagger2.annotations.EnableSwagger2;
import java.util.ArrayList;
/**
* @Author 凉白开_LBK
* @Date 2021/10/25 10:05
* @Explain
*/
@Configuration
@EnableSwagger2 //开启Swagger2
public class SwaggerConfig {
//配置Swagger的Docket的bean实例
@Bean
public Docket docket(){
return new Docket(DocumentationType.SWAGGER_2).apiInfo(apiInfo());
}
//配置Swagger信息 = apiInfo
private ApiInfo apiInfo(){
Contact contact = new Contact(
"凉白开_LBK","http://www.baidu.com","2974087270@qq.com");
return new ApiInfo(
"LBK 's Swagger Api word",
"莫愁前路无知己,天下谁人不识君",
"v1.0",
"http://baidu.com",
contact,
"Apache 2.0",
"http://www.apache.org/licenses/LICENSE-2.0",
new ArrayList<>());
}
}
Swagger配置扫描接口
Docket.select()
//配置Swagger的Docket的bean实例
@Bean
public Docket docket(){
return new Docket(DocumentationType.SWAGGER_2)
.apiInfo(apiInfo())
.select()
// RequestHandlerSelectors:配置要扫描的包
// basePackage():指定要扫描的包
// any():扫描全部
// none():都不扫描
// withClassAnnotation:扫描类上的注解,参数是一个注解的反射对象,例:withClassAnnotation(RestController.class)
// withMethodAnnotation:扫描方法上的注解,参数是一个注解的反射对象,这个是方法,上面的是类
.apis(RequestHandlerSelectors.basePackage("com.lbk.swagger"))
// 设置扫描范围:只有范围内的接口才能生成接口文档
.paths(PathSelectors.ant("/lbk/**"))
.build();
}
配置是否启动Swagger(enable是否启动Swagger,如果为false,则Swagger不能在浏览器中访问)
问题:我只希望我的Swagger在生产环境中使用,在发布的时候不使用
- 判断是不是生产环境 设置变量 flag = false
- 注入enable(flag)
1.先在resources目录下面创建两个properties文件(yml也可以)
2.在docket()方法中加入形参Environment来获取application.yml中设置的环境
application.yml中配置的是spring.profiles.active=dev
application-dev.yml中配置的是server.port=8081
application-pro.yml中配置的是server.port=8082
在浏览器中请求http://localhost:8081/swagger-ui.html就可以访问到Swagger
如果我们把application.yml中的配置的环境改成pro,再通过http://localhost:8082/swagger-ui.html就访问不到了,因为我们能访问到的环境只有dev和test,所以当环境为pro时,flag为false,所以enable(false),不能访问swagger-ui界面
配置API文档的分组
.groupName()
package com.lbk.swagger.entities;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
/**
* @Author 凉白开_LBK
* @Date 2021/10/25 11:15
* @Explain
*/
@ApiModel("用户实体类")
public class User {
@ApiModelProperty("用户名")
private String username;
@ApiModelProperty("密码")
private String password;
}
package com.lbk.swagger.controller;
import com.lbk.swagger.entities.User;
import io.swagger.annotations.ApiOperation;
import io.swagger.annotations.ApiParam;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
/**
* @Author 凉白开_LBK
* @Date 2021/10/25 10:08
* @Explain
*/
@RestController
public class HelloController {
@RequestMapping("/HelloWorld")
public String hello(){
return "hello,world";
}
// 只要我们的接口中,返回值中存在实体类, 他就会扫描到Swagger中
@PostMapping(value = "/user")
public User user(){
return new User();
}
@ApiOperation("hello控制类")
@GetMapping(value = "/hello2")
public String hello2(@ApiParam("用户名") String username){
return "hello " + username;
}
@ApiOperation("Post测试类")
@PostMapping(value = "/postt")
public User postt(@ApiParam("用户名") User user){
return user;
}
}
接口测试
以上面的控制器为例,有下面几种情况
- 正常,不需要参数,或者参数不需要描述
- 如果接口需要参数,并且在参数前使用@ApiParam添加描述这样的话,如果不做任何措施,后端将拿不到参数(null)
- 由url携带参数,参数从url请求地址中获取
- 在每个参数前添加@RequestParam注解来获取参数,url地址不需要设置参数变量
正常,不需要参数
/**
* 不需要参数的方法测试
*/
@ApiOperation("/第一个测试接口")
@GetMapping("/test01")
public String test01(){
return "The result are success";
}
参数不需要添加@ApiParam进行描述
/**
* 参数不需要添加@ApiParam进行描述
* @param username
* @return
*/
@ApiOperation("/第二个测试接口")
@GetMapping("/test02")
public String test02(String username){
return "Hello" + username;
}
如果接口需要参数,并且在参数前使用@ApiParam添加描述这样的话,如果不做任何措施,后端将拿不到参数(null)
/**
* 如果接口需要参数,并且在参数前使用@ApiParam添加描述并且接收参数不做任何措施
* @param username
* @return
*/
@ApiOperation("/第三个测试接口")
@PostMapping("/test03")
public String test03(@ApiParam("用户名") String username){
System.out.println(username);
return username;
}
由url携带参数,参数从url请求地址中获取
/**
* 由url携带参数,参数从url请求地址中获取
* @param username
* @return
*/
@ApiOperation("/第四个测试接口")
@PostMapping("/test04/{username}")
public String test04(@PathVariable @ApiParam("用户名") String username){
System.out.println(username);
return username;
}
在每个参数前添加@RequestParam注解来获取参数,url地址不需要设置参数变量
/**
* 在每个参数前添加@RequestParam注解来获取参数,url地址不需要设置参数变量
* @param username
* @return
*/
@ApiOperation("/第五个测试接口")
@PostMapping("/test05")
public String test05(@RequestParam @ApiParam("用户名") String username){
return "LBK : "+username;
}
生成实体类文档
实体类
package com.lbk.swagger.entities;import
io.swagger.annotations.ApiModel;import
io.swagger.annotations.ApiModelProperty;
import lombok.Data;
import lombok.experimental.Accessors;
/**
* @Author 凉白开_LBK
* @Date 2021/10/25 11:15
* @Explain
*/
@Data@Accessors(chain = true)
@ApiModel(value = "用户实体类", description = "描述")
public class User {
@ApiModelProperty("用户名")
private String userName;
@ApiModelProperty("密码")
private String password;
}
swagger-ui界面中的Models信息
代码中用到的注解和方法的作用
注解或方法 | 作用 |
---|---|
@EnableSwagger2 | 开启Swagger2,用于Swagger配置类上 |
Docket | 实例化一个信息类,这个信息类实现了一个信息插件 |
Profiles.of(“dev”,“test”) | 设置要获取的swagger环境 |
environment.acceptsProfiles(profiles) | 判断当前是否处在设定的环境中,返回值为boolean值 |
DocumentationType.SWAGGER_2 | Swagger的版本 |
.apiInfo() | 页面中显示的信息,例如作者名之类的 |
.enable() | 配置是否自动开启Swagger,false为不开启,true为开启 |
.select() | 选择扫描 |
RequestHandlerSelectors | 配置以扫描包的方式扫描 |
basePackage() | 指定所要扫描的包 |
any() | 扫描全部 |
ant() | 指定扫描 |
none() | 都不扫描 |
withClassAnnotation | 以扫描注解的反射对象的方式扫描,例如:withClassAnnotation(RestController.class) |
withMethodAnnotation | 扫描方法上的注解,参数是一个注解的反射对象,这个是方法,上面的是类 |
.paths() | 设置扫描范围,只有在这个范围中才能被扫描到,范围外扫描不到,也就是无法在页面中展示 |
.build() | 构建一个Docket实例 |
Contact | 配置个人信息,参数为name、url、email |
@ApiOperation() | 添加在方法上,用于描述方法 |
@ApiModel() | 添加在类上,用于描述类,一般用于实体类 |
@ApiModelProperty() | 添加在属性上,用于描述属性,一般用于实体类中 |
总结
Swagger是一个开源的,可以用来测试的,自动化生成接口文档的工具,它的出现降低了前后端的沟通成本,实现了一旦更改,即时发现的功能,总而言之,是一个非常强大的工具