1、什么是Sawgger
是一款部署在后端的接口文档工具,提供了在线同步的接口文档,解决前后端分离时代接口不能及时协商与解决的问题。
2、怎么在Spring boot项目中使用?
创建一个基本的spring boot项目,勾选web即可。
2.1 首先导入依赖
这里选取的是2.9.2的版本,目前是使用最多的。
<dependency>
<groupId>io.springfox</groupId>
<artifactId>springfox-swagger2</artifactId>
<version>2.9.2</version>
</dependency>
<dependency>
<groupId>io.springfox</groupId>
<artifactId>springfox-swagger-ui</artifactId>
<version>2.9.2</version>
</dependency>
2.2 创建一个Swagger配置文件,使用@EnableSwagger2
开启
package cn.butcher.config;
import org.springframework.context.annotation.Configuration;
import springfox.documentation.swagger2.annotations.EnableSwagger2;
@Configuration
@EnableSwagger2
public class SwaggerConfig {
}
在浏览器中输入http://localhost:8080/swagger-ui.html
2.3 Swagger配置
每个Swagger都有一个Docket
实例,通过这个实例来操作Swagger的页面。
在SwaggerConfig
中,我们注入:
package cn.butcher.config;
@Configuration
@EnableSwagger2
public class SwaggerConfig {
@Bean
public Docket docket(Environment environment){
// Docket中有一个apiInfo()方法可以设置基本信息
return new Docket(DocumentationType.SWAGGER_2)
.apiInfo(apiInfo());
}
@Bean
public ApiInfo apiInfo(){
// 从上到下是:标题、描述、版本号、条款链接、联系我、许可证、许可证链接
return new ApiInfo(
"butcher的Api文档",
"api文档描述",
"v1.0",
"http://blog.butcher21.cn",
new Contact("谭熙", "http://blog.butcher21.cn", "tanxi@qq.com"),
"Apache 2.0",
"http://www.apache.org/licenses/LICENSE-2.0",
new ArrayList<>());
}
}
设置完毕后的页面为:
2.4 如何配置在开发环境开启Swagger,在线上环境关闭Swagger
这里主要是思路,首先我们要能获取到当前是什么环境,判断这个环境。
我们需要知道,可以在Docket实例有一个enable(boolean flag)方法可以开启和关闭。
这里我的实现方式为:
@Bean
public Docket docket(Environment environment){
// Environment是spring中获取当前项目环境的接口
String[] activeProfiles = environment.getActiveProfiles();
List<String> envs = Arrays.asList(activeProfiles);
boolean flag = false;
// 判断当前是开发环境或者测试环境,就开启Swagger
if (envs.contains("dev") | envs.contains("test")){
flag = true;
}
return new Docket(DocumentationType.SWAGGER_2)
.apiInfo(apiInfo())
.enable(flag)
// 设置组名,也就是Swagger右上角的内容
.groupName("01组")
.select()
// 配置要扫描的包
.apis(RequestHandlerSelectors.basePackage("cn.butcher.controller"))
.build();
}
注意:并不是只有这一种方法
- 完全可以自己写一个propertie读取里面的配置。
- 在SwaggerConfig上使用@Profile注解标识,@Profile({“dev”,“test”})表示在dev和test环境才能访问swagger-ui.html,prod环境下访问不了。
- 在SwaggerConfig上使用@ConditionalOnProperty注解,@ConditionalOnProperty(name = “swagger.enable”, havingValue = “true”)
2.5 配置要扫描的包
我们可以配置Swagger要扫描的接口,上面的代码注明了:可以通过select()方法管理接口;
apis()
:要扫描的包
paths()
:要过滤的接口
记得最后要通过build()
一下。
apis()
中需要Predicate
类型为RequestHandler
可以通过RequestHandlerSelectors
获取:
public class RequestHandlerSelectors {
// 扫描所有
public static Predicate<RequestHandler> any() {}
// 什么都不扫描
public static Predicate<RequestHandler> none() {}
// 扫描方法上的注解
public static Predicate<RequestHandler> withMethodAnnotation(final Class<? extends Annotation> annotation) {}
// 扫描类上的注解
public static Predicate<RequestHandler> withClassAnnotation(final Class<? extends Annotation> annotation) {}
private static Function<Class<?>, Boolean> annotationPresent(final Class<? extends Annotation> annotation) { }
// 扫描handler个包
private static Function<Class<?>, Boolean> handlerPackage(final String basePackage) {}
// 扫描某个包(重点!!!)
public static Predicate<RequestHandler> basePackage(final String basePackage) {}
private static Optional<? extends Class<?>> declaringClass(RequestHandler input) {}
}
2.6 设置多个组
Swagger中,一个Docket实例是一组,所以我们可以配置多个实例,做到协作开发!
例如:
@Bean
public Docket docket(Environment environment){
return new Docket(DocumentationType.SWAGGER_2)
.apiInfo(apiInfo())
.enable(flag)
// 组的名字
.groupName("01组")
.select()
.apis(RequestHandlerSelectors.basePackage("cn.butcher.controller"))
.build();
}
@Bean
public Docket docket2(Environment environment){
return new Docket(DocumentationType.SWAGGER_2)
.apiInfo(apiInfo())
.enable(flag)
.groupName("02组")
.select()
.apis(RequestHandlerSelectors.basePackage("cn.butcher.controller"))
.build();
}
3、注解
我们可以通过注解来描述我我们的接口。
3.1 准备接口
创建User实体类:
package cn.butcher.pojo;
public class User {
private String username;
private String password;
private char sex;
private int age;
private boolean passCET4;
private Date birth;
}
// 以上省略了set方法
创建UserController接口:
package cn.butcher.controller;
@RestController
public class UserController {
@GetMapping("/hello")
public String hello(String name){
return "hello " + name;
}
@GetMapping("/user")
public User getUser(String name){
User user = new User();
user.setUsername(name);
user.setPassword("tanxi");
user.setAge(18);
user.setPassCET4(false);
user.setSex('男');
user.setBirth(new Date());
return user;
}
}
先看看效果:
可以看到两个接口已经被扫描到了,我们的实体类也扫描到了,我们需往上加上我们自己的注释,这时候我们就需要用到注解了,先介绍常用注解:
@Api() 作用在类上,表示一组api
- value 副标题
- tags 标题
- authorizations 权限
- hidden 是否显示
- produces 生产
- consumes 消费
- protocols 协议
@ApiOperation() 作用在方法上,表示一个接口的描述
- value
- notes
- tags
- response
- nickname
....
@ApiParam() 作用在方法参数上,描述一个请求参数
- name 参数名
- value 描述
- defaultValue 默认值
- allowableValues
- required
- format
....
@ApiModel() 作用在实体类上,描述这个数据
- value
- description
- parent
- reference
....
@ApiModelProperty(),作用在实体类的属性上,描述这个属性。
- value
- name
- allowableValues
- access
- notes
....
@ApiResponse(),作用在方法上,描述响应信息。
- code 状态码
- message 信息
- response 响应类型
....
@ApiIgnore() 不显示这个接口
3.2 实例:
@ApiModel("用户数据")
public class User {
@ApiModelProperty("用户名")
private String username;
@ApiModelProperty("密码")
private String password;
@ApiModelProperty("性别")
private char sex;
@ApiModelProperty("年龄")
private int age;
@ApiModelProperty("是否过了四级")
private boolean passCET4;
@ApiModelProperty("出生日期")
private Date birth;
}
@Api(value = "UserController" ,tags = "用户接口")
@RestController
public class UserController {
@ApiOperation("对某人说hello")
@GetMapping("/hello")
public String hello(@RequestParam @ApiParam("姓名") String name){
return "hello " + name;
}
@ApiOperation(value = "获取用户", notes = "现在只能改变姓名哦")
@ApiResponses({@ApiResponse(code = 200,message = "请求成功"),@ApiResponse(code = 500,message = "请求失败")})
@GetMapping("/user")
public User getUser(@RequestParam @ApiParam("姓名") String name){
User user = new User();
user.setUsername(name);
user.setPassword("tanxi");
user.setAge(18);
user.setPassCET4(false);
user.setSex('男');
user.setBirth(new Date());
return user;
}
}
4、接口测试
我们现在测试 /user
这个接口,点击接口右上角的try it out
说明接口测试成功。
至此,Swagger就暂时就没有什么了~