整合Swagger
在现在的web开发中,前后端分离的开发模式大行其道,前端负责页面渲染,并发送请求到后端服务器请求数据,后端负责数据访问和处理,然后返回数据给前端
在前后端开发的模式中,接口的定义在协同开发中就非常重要,前端开发人员需要清晰地知道后端接口的用途,需要的参数和返回的数据,因此在开发中需要一份接口文档。Swagger是一款流行的Api框架,他可以定义Api接口的参数和返回值,并且支持同步更新和在线调试,解决了这个问题
基本使用
使用Swagger,需要导入Swagger的starter依赖,本文以Swagger3为例,Swagger2的用法和Swagger3会有少许不同
<dependency>
<groupId>io.springfox</groupId>
<artifactId>springfox-boot-starter</artifactId>
<version>3.0.0</version>
</dependency>
配置Swagger配置类,将@EnableOpenApi
注解添加在配置类或者启动类上
在容器中添加一个ApiInfo组件和Docket组件,ApiInfo组件用于描述项目的内容,作者以及License等信息,Docket组件用于设置接口文档需要扫描的接口
@Configuration
@EnableOpenApi
public class SwaggerConfig {
@Bean
public Docket createRestApi(ApiInfo apiInfo) {
return new Docket(DocumentationType.OAS_30)
.apiInfo(apiInfo)
.select()
// 扫描接口,支持按包扫描,按注解扫描,全部扫描,全部不扫描
.apis(RequestHandlerSelectors.withMethodAnnotation(ApiOperation.class))
// 过滤的路径,支持按路径匹配,按正则表达式匹配,全部匹配,全部不匹配
.paths(PathSelectors.any())
.build();
}
@Bean
public ApiInfo apiInfo() {
Contact contact = new Contact("葱酱", "https://blog.youkuaiyun.com/blackball1998", "425017255@qq.com");
return new ApiInfoBuilder()
.title("我的项目")
.description("我的项目介绍")
.version("1.0")
.termsOfServiceUrl("https://blog.youkuaiyun.com/blackball1998")
.contact(contact)
.license("Apache 2.0")
.licenseUrl("http://www.apache.org/licenses/LICENSE-2.0")
.build();
}
}
在接口类中添加@Api
注解,设置接口类的作用,在接口上添加@ApiOperation
注解,设置接口的作用
@Api(tags = "测试相关类")
@RestController
public class MyController {
@ApiOperation(value = "测试接口", notes = "备注:这是一个测试接口")
@GetMapping("/test")
public String test(@RequestParam("name") String name) {
return "success";
}
}
设置完成后,启动项目,访问项目下的**/swagger-ui/index.html**地址,可以得到Swagger自动生成的文档页面,页面中有项目的描述信息,包括在配置类中设置的个人信息
扫描到的接口类也会出现在页面中,点开可以查看接口的请求方式,参数和返回值等信息
点击接口文档中的Try it out按键,还可以发送请求进行调试
添加参数和返回值说明
如果接口的参数或者返回值是用实体类表示的,我们还可以在参数类和返回类上添加参数和返回值的信息,比如我们的接口使用一个TestReqVO对象来接收,然后用一个TestResVO对象来返回
在VO类上添加@ApiModel
注解,设置参数和返回的说明,然后在类的属性上添加@ApiModelProperty
注解,设置每一个参数属性和返回值属性的说明
@Data
@ApiModel("测试接口参数")
public class TestReqVO {
@ApiModelProperty("名字")
String name;
@ApiModelProperty("编号")
String code;
}
@Data
@ApiModel("测试接口返回")
public class TestResVO {
@ApiModelProperty("状态")
String state;
@ApiModelProperty("住址")
String address;
@ApiModelProperty("邮箱")
String email;
}
只要在被Swagger扫码到的接口使用了这个VO作为参数或者返回值,Swagger就会将VO的信息添加在文档中
@Api(tags = "测试相关类")
@RestController
public class MyController {
@GetMapping("/test")
@ApiOperation(value = "测试接口", notes = "备注:这是一个测试接口")
public TestResVO test(TestReqVO vo) {
return new TestResVO();
}
}
接口文档分组
在开发中,往往后台由多个人来开发,每个人开发自己的模块。Swagger支持文档分组的功能,每个人将自己的接口放在自己的组中,分别编写各自的接口说明文档
使用文档分组,只需要在Swagger配置类中添加多个Docket
组件,每个组件设置不同的Bean名称,然后在不同的Docket中扫描不同的接口,这样就可以以每个Docket为一组分组
@Configuration
@EnableOpenApi
public class SwaggerConfig {
@Bean
public Docket docketA(ApiInfo apiInfo) {
return new Docket(DocumentationType.OAS_30)
.groupName("groupA")
.apiInfo(apiInfo)
.select()
.apis(RequestHandlerSelectors.basePackage("com.blackball.groupA.controller"))
.paths(PathSelectors.any())
.build();
}
@Bean
public Docket docketB(ApiInfo apiInfo) {
return new Docket(DocumentationType.OAS_30)
.groupName("groupB")
.apiInfo(apiInfo)
.select()
.apis(RequestHandlerSelectors.basePackage("com.blackball.groupB.controller"))
.paths(PathSelectors.any())
.build();
}
@Bean
public Docket docketC(ApiInfo apiInfo) {
return new Docket(DocumentationType.OAS_30)
.groupName("groupC")
.apiInfo(apiInfo)
.select()
.apis(RequestHandlerSelectors.basePackage("com.blackball.groupC.controller"))
.paths(PathSelectors.any())
.build();
}
@Bean
public ApiInfo apiInfo() {
Contact contact = new Contact("葱酱", "https://blog.youkuaiyun.com/blackball1998", "425017255@qq.com");
return new ApiInfoBuilder()
.title("我的项目")
.description("我的项目介绍")
.version("1.0")
.termsOfServiceUrl("https://blog.youkuaiyun.com/blackball1998")
.contact(contact)
.license("Apache 2.0")
.licenseUrl("http://www.apache.org/licenses/LICENSE-2.0")
.build();
}
}
打开Swagger页面,可以看到文档右上角有一个分组下拉框,可以按组显示不同的接口
根据环境开启关闭文档
一般情况下,接口文档只需要在开发阶段开放给开发人员阅读,而线上环境需要关闭文档,我们可以在IOC容器中获取Environment
组件,用于判断当前的项目运行环境,然后使用Docket
类的enable
方法来自动开启关闭Swagger
@Configuration
@EnableOpenApi
public class SwaggerConfig {
@Bean
public Docket docket(ApiInfo apiInfo, Environment environment) {
Profiles profiles = Profiles.of("dev", "test");
boolean isEnable = environment.acceptsProfiles(profiles);
return new Docket(DocumentationType.OAS_30)
.enable(isEnable)
.apiInfo(apiInfo)
.select()
.apis(RequestHandlerSelectors.withMethodAnnotation(ApiOperation.class))
.paths(PathSelectors.any())
.build();
}
@Bean
public ApiInfo apiInfo() {
Contact contact = new Contact("葱酱", "https://blog.youkuaiyun.com/blackball1998", "425017255@qq.com");
return new ApiInfoBuilder()
.title("我的项目")
.description("我的项目介绍")
.version("1.0")
.termsOfServiceUrl("https://blog.youkuaiyun.com/blackball1998")
.contact(contact)
.license("Apache 2.0")
.licenseUrl("http://www.apache.org/licenses/LICENSE-2.0")
.build();
}
}
设置项目环境为线上环境
spring:
profiles:
active: pro
这时候打开Swagger文档,发现由于环境条件过滤,Swagger文档已经关闭