Swagger的使用
Swagger 简介
存在问题:
- 前后端分离,无法做到及时协商,及时解决
解决方法:
- 制定 schema【计划的提纲】,实时更新最新 API,降低集成的风险
- 早些年:制定 word 计划文档;
- 前后端分离:
- 前端测试后端分离:postman
- 后端提纲接口,需要实时最新的消息及改动
Swagger
- 号称世界上最流行的 API 框架,
- 围绕 OpenAPI 规范构建的开源工具,RestFul API 文档在线生产工具=> Api文档与 API 定义同步更新
- 直接运行,可以在线测试 API 接口
- 支持多种语言(java,php。。。。)
- 接口文档可以实时动态生成
- 使用 Swagger,就是把相关的信息存储在它定义的描述文件里面 (yml 或 json 格式),再通过维护这个描述文件可以去更新接口文档, 以及生成各端代码
Spring-fox
- spring-fox是基于 spring 的组件,swagger-springmvc。 Spring-fox 就是根据这个组件发展而来的全新项目。
Spring-fox 是根据代码生成接口文档,所以正常的进行更新项目版本,修改代码即可,而不需要跟随修改描述文件。
Spring-fox 利用自身 AOP 特性,把 Swagger 集成进来,底层还是Swagger。但是使用起来确方便很多。 - 是根据 swagger 的封装,完全根据代码生产接口文档,无须再修改描述文件
所以在项目中使用 Swagger只需要使用 springbox即可
- swagger2
- ui
SpringBoot 继承 Swagger
- 新建 SpringBoot web 项目
- 导入相关依赖
<!-- swagger 依赖-->
<dependency>
<groupId>io.springfox</groupId>
<artifactId>springfox-swagger2</artifactId>
<version>2.9.2</version>
</dependency>
<!-- swagger UI依赖-->
<dependency>
<groupId>io.springfox</groupId>
<artifactId>springfox-swagger-ui</artifactId>
<version>2.9.2</version>
</dependency>
- 编写项目
@RestController
@RequestMapping("/people")
public class DemoController {
@RequestMapping("/getpeople")
public People getPeople(int id){
People people = new People();
people.setId(id);
people.setName("北京");
people.setAddress("朝阳");
return people;
}
}
- 配置 Swagger,在启动类添加@EnableSwagger2,重启项目
- 测试运行 ui 地址 http://localhost:8080/swagger-ui.html
配置 Swagger
可以在项目中创建 SwaggerConfig,进行配置文档内容。就是对这部分进行配置
配置基本信息
- Docket:摘要对象,通过对象配置描述文件的信息。
- apiInfo:设置描述文件中 info。参数类型 ApiInfo
- select():返回 ApiSelectorBuilder 对象,通过对象调用 build()可以创建 Docket 对象
- ApiInfoBuilder:ApiInfo 构建器。
- 创建项目配置文件
@Configuration
public class SwaggerConfig {
@Bean
public Docket getDocket() {
return new Docket(DocumentationType.SWAGGER_2).apiInfo(getApiInfo()).select().build();
}
private ApiInfo getApiInfo() {
return new ApiInfoBuilder()
.title("第一个 swagger 的标题")
.description("这里是描述")
.version("1.0.0")
//联系信息
.contact(new Contact("这是名称", "这是 url", "这是 email"))
.build();
}
}
- 结果
设置扫描包
- 通过 apis()方法设置哪个包中内容被扫描
@Bean
public Docket getDocket() {
return new Docket(DocumentationType.SWAGGER_2)
.apiInfo(getApiInfo())
.select()
.apis(RequestHandlerSelectors.basePackage("com.example.swagger.controller"))
.build();
}
自定义接口不需要生成接口文档
- 注解名称随意取
@Target(ElementType.METHOD)//写在方法上
@Retention(RetentionPolicy.RUNTIME)//运行时解析
public @interface NotIncludeSwagger {
}
- 设置规则
- 通 过 public ApiSelectorBuilder apis(Predicate selector)可以设置生成规则。
- public static Predicate not(Predicate predicate) :表示不 允许的条件。
- withMethodAnnotation:表示此注解是方法级别注解。
@Bean
public Docket getDocket() {
return new Docket(DocumentationType.SWAGGER_2)
.apiInfo(getApiInfo())
.select()
.apis(RequestHandlerSelectors.basePackage("com.example.swagger.controller"))
.apis(not(withMethodAnnotation(NotIncludeSwagger.class)))//使用这个注解就不能实现接口文档
.build();
}
- 在不需要生成接口文档的方法上面添加@NotIncludeSwagger 注解后,该方法将不会被 Swagger 进行生成在接口文档中。
设置范围
- 通过 public ApiSelectorBuilder paths(Predicate selector)可 以设置满足什么样规则的 url 被生成接口文档。可以使用正则表达式 进行匹配。
- 下面例子中表示只有以/people/开头的url 才能被 swagger 生成接口文档。也可以设置多个 url 地址
- 如何希望全部扫描可以使用 paths(PathSelectors.any())
@Bean
public Docket getDocket() {
return new Docket(DocumentationType.SWAGGER_2)
.apiInfo(getApiInfo())
.select()
.apis(RequestHandlerSelectors.basePackage("com.example.swagger.controller"))
.apis(not(withMethodAnnotation(NotIncludeSwagger.class)))//使用这个注解就不能实现接口文档
//设置一个
.paths(PathSelectors.regex("/people/.*"))
//设置多个 url 范围生成接口文档
.paths(or(PathSelectors.regex("/people/.*"),PathSelectors.regex("/demo/.*")))
.build();
}
Swagger 常用注解
- API 注解
@Api 是类上注解。控制整个类生成接口信息的内容。
tags:类的名称。可以有多个值,多个值表示多个副本。
description:描述,已过时。
这个注解就是控制在 ui.html 页面的类名称和描述,只能用在类上
@RestController
@RequestMapping("/people")
@Api(tags = {"mydemo"},description = "描述")
public class DemoController {
@PostMapping("/getpeople")
public People getPeople(int id){
People people = new People();
people.setId(id);
people.setName("北京");
people.setAddress("朝阳");
return people;
}
}
- 页面显示内容修改前和添加 api 注解后
- @ApiOperation 写在方法上,对方法进行总体描述
value:接口描述
notes:提示信息
@ApiOperation(value = "获取人的内容",notes = "通过人的编号查询信息")
public People getPeople(int id){
}
public People getPeople(@ApiParam(name = "这是 id",value = "这是 value",required = true) int id){
}
- ui 页面前后对比
- ApiModel
@ApiModel 是类上注解,主要应用 Model,也就是说这个注解一 般都是写在实体类上。
value:名称
description:描述
@ApiModel(value = "人实体类",description = "实体类封装类 People 的全部属性")
public class People {
}
- ApiModelProperty
@ApiModelProperty 可以用在方法或属性上。用于当对象作为参 数时定义这个字段的内容。
value:描述
name:重写属性名
required:是否是必须的
example:示例内容
hidden:是否隐藏,默认是 false 不隐藏
public class People {
@ApiModelProperty(value = "编号",name = "id",required = true,example = "123")
private int id;
private String name;
@ApiModelProperty(hidden = true)
private String address;
}
- ApiIgnore
@ApiIgnore 用于方法或类或参数上,表示这个方法或类被忽略。 和之前讲解的自定义注解@NotIncludeSwagger 效果类似。只是这个注解是Swagger内置的注解,而@NotIncludeSwagger是我们自定义的注解。 - ApiImplicitParam
@ApiImplicitParam 用在方法上,表示单独的请求参数,总体功能 和@ApiParam (多数用于方法参数上) 类似。
name:属性名
value:描述
required:是否是必须的
paramType:属性类型
dataType:数据类型
@PostMapping("/getpeople2")
@ApiImplicitParam(name = "id",value = "编号",paramType = "body",dataType = "int")//这个注解只能写一个
public People getPeople1(int id,String name){
return null;
}
- 要为多个属性进行设置使用@ApiImplicitParams
@PostMapping("/getpeople2")
@ApiImplicitParams(value ={@ApiImplicitParam(name = "id",value = "编号",required = true),@ApiImplicitParam(name = "name",value = "姓名")} )
public People getPeople1(int id,String name){
return null;
}
SpringBoot继承Swagger
导入依赖
编写一个 controller
@RestController
public class HelloController {
@GetMapping("/hello")
public String hello(){
return "hello";
}
//只要接口中存在实体类就能扫描到
@PostMapping("/hi")
public User user(){
return new User();
}
@ApiOperation("user方法")//用在方法上
@PostMapping("/user")
public String user1(@ApiParam("传入姓名参数") String name){
return name;
}
}
swagger 配置文件
Swagger 的 bean 实例 Docket
@Configuration
@EnableSwagger2//开启 swagger2
public class SwaggerConfig {
//配置 swagger 的 bean 实例
@Bean
public Docket docket(){
return new Docket(DocumentationType.SWAGGER_2)
.apiInfo(apiInfo());
}
public ApiInfo apiInfo(){
return new ApiInfo(
"Swagger 文档",
"学好 swagger",
"1.0",
"http://www.baidu.com/",
new Contact("本人", "http://www.baidu.com/", "714860063@qq.com"),
"Apache 2.0",
"http://www.apache.org/licenses/LICENSE-2.0",
new ArrayList());
}
}
Swagger 配置扫描接口
@Configuration
@EnableSwagger2//开启 swagger2
public class SwaggerConfig {
//配置 swagger 的 bean 实例
@Bean
public Docket docket(){
return new Docket(DocumentationType.SWAGGER_2)
.apiInfo(apiInfo())
.select()
//RequestHandlerSelectors,配置要扫描接口的方式
//basePackage:指定 扫描包;none() ,不扫描
//withClassAnnotation :扫描类上注解 比如:@RestController
//withMethodAnnotation :扫描类上注解 比如: @RequestMapping()
.apis(RequestHandlerSelectors.basePackage("com.study.controller"))
.paths(PathSelectors.ant("/study/**"))//过滤路径
.build();
}
public ApiInfo apiInfo(){
return new ApiInfo(
"Swagger 文档",
"学好 swagger",
"1.0",
"http://www.baidu.com/",
new Contact("本人", "http://www.baidu.com/", "714860063@qq.com"),
"Apache 2.0",
"http://www.apache.org/licenses/LICENSE-2.0",
new ArrayList());
}
}
配置是否启动 swagger
//配置 swagger 的 bean 实例
@Bean
public Docket docket(){
return new Docket(DocumentationType.SWAGGER_2)
.apiInfo(apiInfo())
.enable(false)//是否启用 swagger,false 则不能在浏览器访问
.select()
.apis(RequestHandlerSelectors.basePackage("com.study.controller"))
.build();
}
如何动态配置在不同环境中是否启用 swagger
@Configuration
@EnableSwagger2//开启 swagger2
public class SwaggerConfig {
//配置 swagger 的 bean 实例
@Bean
public Docket docket(Environment environment){
//配置文件中的生成环境 spring.profiles.active=dev
//设置要显示的 swagger,一般生成环境,需要设置
Profiles profiles = Profiles.of("dev", "test");
//判断是否在设置的生产环境中
boolean flag = environment.acceptsProfiles(profiles);
System.out.println(flag);
return new Docket(DocumentationType.SWAGGER_2)
.groupName("张三")
.apiInfo(apiInfo())
.enable(flag)//是否启用 swagger,false 则不能在浏览器访问
.select()
.apis(RequestHandlerSelectors.basePackage("com.study.controller"))
.build();
}
}
配置 API 文档分组
(多人开发时,每个人维护自己的组即可),配置多个组就配置不同名的 Docke 就可以实现
@Bean
public Docket docket1(){
return new Docket(DocumentationType.SWAGGER_2)
.groupName("李四");
}
常用的注解
//ApiModel 是为了写个注释
@ApiModel("用户实体类")//用在实体类
public class User {
@ApiModelProperty("用户名")//用在属性上
public int id;
@ApiModelProperty("密码")
public String name;
}
@RestController
public class HelloController {
@GetMapping("/hello")
public String hello(){
return "hello";
}
//只要接口中存在实体类就能扫描到
@PostMapping("/hi")
public User user(){
return new User();
}
@ApiOperation("user方法")//用在方法上
@PostMapping("/user")
public String user1(@ApiParam("传入姓名参数") String name){
return name;
}
}
测试功能
总结:
- 我们可以通过 swagger 给一些比较难理解的属性或接口,增加注释信息
- 接口文档的实时更新
- 可以在线测试
- !!!注意点:正式发布时候关闭 swagger