1、前言
①在前后端分离开发中,一般需要构建一份API文档来描述所有接口信息,文档工作量巨大,需要包含接口地址、请求参数以及返回值等,且维护不方便,一旦接口发生变化就需要修改文档。
②Swagger的出现可以帮助开发人员快速设计、构建、记录、使用RESTFul API/Web服务。它将代码和文档融为一体,完美解决上述问题,将开发人员的精力集中到业务中,而不是繁琐的文档。
③网上很多Swagger教程均基于Swagger2,现均已过时,而本文将带来全新Swagger3.0教程,以最简单的方式实现Swagger3(OAS3)快速配置上手,实现API接口文档自动化。
2、开发工具及版本
JAVA11或者JAVA13
Spring-boot 2.5+
3、Swagger3.0与Swagger2的主要差异:
①Swagger3通过@EnableOpenApi注解开启应用,而Swagger2通过@EnableSwagger2注解开启应用。
②依赖有所不同,见下文。
③访问网址不同,Swagger3是http://localhost:8080/swagger-ui/index.html,Swagger2是http://localhost:8080/swagger-ui.html,这个要特别注意。
4、项目整合使用Swagger3.0配置完整过程
1、创建Spring-boot Web项目,添加Swagger3.0相关依赖,代码如下:
<dependency>
<groupId>io.springfox</groupId>
<artifactId>springfox-boot-starter</artifactId>
<version>3.0.0</version>
</dependency>
原Swagger2需要引入下面两个依赖,这里我们了解即可。
<dependency>
<groupId>io.springfox</groupId>
<artifactId>springfox-swagger2</artifactId>
<version>3.0.0</version>
</dependency>
<dependency>
<groupId>io.springfox</groupId>
<artifactId>springfox-swagger-ui</artifactId>
<version>3.0.0</version>
</dependency>
2、接下来创建Swagger3.0配置类Swagger3Config,项目结构树和代码如下:
这里我们特别注意:
①apis(RequestHandlerSelectors.basePackage("com.example.demohelloworld.swagger3.controller")),表明扫描该包下面所有的Controller接口类。
②apis(RequestHandlerSelectors.any())表明扫描所有满足条件的Controller接口类。
③paths(Predicate.not(PathSelectors.regex("/error.*")))表明排除某个路径,在RESTFul接口中有时候需要排除"/error.*"等接口,只需要加入上述代码即可,regex()表明符合正则的路径。
④还有一个地方很容易被忽略,Swagger3的访问网址swagger-ui/index.html是放在META-INF/resources下面,所以我们需要加入资源映射,确保能够访问。映射的地址是/META-INF/resources/webjars/springfox-swagger-ui/。
package com.example.demohelloworld.swagger3.config;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.servlet.config.annotation.ResourceHandlerRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;
import springfox.documentation.builders.ApiInfoBuilder;
import springfox.documentation.builders.PathSelectors;
import springfox.documentation.builders.RequestHandlerSelectors;
import springfox.documentation.oas.annotations.EnableOpenApi;
import springfox.documentation.service.Contact;
import springfox.documentation.spi.DocumentationType;
import springfox.documentation.spring.web.plugins.Docket;
import java.util.function.Predicate;
@Configuration
//@EnableOpenApi开启SWAGGER3.0
@EnableOpenApi
public class Swagger3Config implements WebMvcConfigurer {
@Bean
//同Swagger2相似,主要是配置一个Docket
Docket docket(){
//DocumentationType.OAS_30,原Swagger2选择DocumentationType.SWAGGER_2
return new Docket(DocumentationType.OAS_30)
.select()
//通过apis方法配置要扫描的controller的位置
.apis(RequestHandlerSelectors.basePackage("com.example.demohelloworld.swagger3.controller"))
//通过paths方法配置路径
.paths(PathSelectors.any())
//设置需要排除的路径(如果需要)
.paths(Predicate.not(PathSelectors.regex("/error.*")))
.build().apiInfo(new ApiInfoBuilder()
//设置文档标题
.description("Swagger3测试API接口文档")
//设置联系人信息
.contact(new Contact("API作者","https://www.csdn.net","lulc@163.com"))
//设置版本号
.version("1.1")
//设置文档抬头
.title("API测试文档")
//设置授权
.license("License By lulu")
//设置授权访问网址
.licenseUrl("https://swagger.io")
.build());
}
@Override
//swagger-ui/index.html在META-INF/resources下面,添加资源映射确保URL能够访问
public void addResourceHandlers(ResourceHandlerRegistry registry){
registry.addResourceHandler("/swagger-ui/**").addResourceLocations("classpath:/META-INF/resources/webjars/springfox-swagger-ui/")
.resourceChain(false);
}
}
3、Swagger3Config配置完成后,我们创建一个测试接口ApiController就可以开始测试了。
首先我们了解Swagger3一些常用注解的含义:
@Api:用在类上,用来描述整个Controller接口信息。
@ApiOperation:用在方法上,用来描述方法的基本信息,value是对方法作用的简短描述,notes则是该方法的详细描述。
@ApiImplicitParam:用在方法上,用来描述方法的参数,paramType是指方法参数类型,可选值有path(参数获取方式@PathVariable)、query(参数获取方式@RequestParam)、header(参数获取方式@RequestHeader)、body(参数获取方式@RequestBody)以及form,name表示参数名字,和参数名字对应,value则是参数描述信息。required表示该字段是否必填,defaultValue表示该字段的默认值,注意,这里的required和defaultValue不具备真正的约束性仅为文档显示,真正的还需要在@RequestParam中设置。
@ApiImplicitParams:如果是多参数,可将多个参数放在@ApiImplicitParams中,格式为@ApiImplicitParams({@ApiImplicitParam(paramType="query",name="username"),@ApiImplicitParam(paramType="path",name="userid")})。
@ApiResponse:对响应结果的描述,code表示响应码,@message表示描述信息,如果有多个@ApiResponse,可以放在一个@ApiResponses中。
@ApiResponses:格式为@ApiResponses({@ApiResponse(code = 200,message = "删除成功!"),@ApiResponse(code = 500,message = "删除失败!")})。
@ApiModel:一般用于响应类上,表示一个返回响应数据的信息(如updateUse方法,请求参数无法使用@ApiImplicitParam注解进行描述的时候)。
@ApiModelProperty:用在属性上,描述响应类的属性。
@ApiIgnore:表述不对某个接口生成文档,即忽略这个接口。
接下来我们在Controller层创建测试接口ApiController,将以上注解写入相应的位置。在RESTFul API接口中,书写注解的位置可以是@Repository,也可以是@Service。
Controller调用Service,Service调用Dao(Repository),是常见的MVC三层模型。而Swagger灵活的地方就是可以在这三层中需要的位置任意书写。
package com.example.demohelloworld.swagger3.controller;
import io.swagger.annotations.*;
import org.springframework.web.bind.annotation.*;
import springfox.documentation.annotations.ApiIgnore;
@RestController
//@Api:用在类上,用来描述整个Controller接口信息。
@Api(tags = "用户数据接口")
public class ApiController {
//@ApiOperation:用在方法上,用来描述方法的基本信息
@ApiOperation(value = "查询用户" ,notes = "根据ID查询用户")
//@ApiImplicitParam:用在方法上,用来描述方法的参数
@ApiImplicitParam(paramType = "path",name = "id",value = "用户id",required = true,dataType = "String",dataTypeClass = String.class)
@GetMapping("/user/{id}")
public String getUserByID(@PathVariable Integer id){
return "userid:"+ id;
}
//@ApiResponse:对响应结果的描述
@ApiResponses({@ApiResponse(code = 200,message = "删除成功!"),@ApiResponse(code = 500,message = "删除失败!")})
@ApiOperation(value = "删除用户", notes = "删除用户BYid")
@DeleteMapping("/user/{id}")
public String deleteUserById(@PathVariable Integer id){
return "删除用户:"+id;
}
@ApiOperation(value = "添加用户",notes = "添加一个用户,传入用户名和地址")
//@ApiImplicitParams:如果是多参数,可将多个参数@ApiImplicitParam放在@ApiImplicitParams中
@ApiImplicitParams({@ApiImplicitParam(paramType = "query",name = "username",value = "传入用户名",required = true,defaultValue = "lulu",dataType = "String",dataTypeClass = String.class),
@ApiImplicitParam(paramType = "query",name = "address",value = "传入地址",required = true,defaultValue = "深圳",dataType = "String",dataTypeClass = String.class)})
@PostMapping("/user")
public String addUser(@RequestParam String username,@RequestParam String address){
return "添加用户:"+username+" 地址:"+address;
}
@ApiOperation(value = "修改用户",notes = "修改用户,传入用户信息")
@PutMapping("/user")
public String updateUser(@RequestBody Users user){
return "修改用户"+user.getUsername()+user.getAddress();
}
//@ApiIgnore:表述不对某个接口生成文档
@GetMapping("/ignore")
@ApiIgnore
public void ignore(){
}
//@ApiModel:一般用于响应类上,表示一个返回响应数据的信息
@ApiModel(value = "用户实体类",description = "用户信息描述")
public static class Users{
//@ApiModelProperty:用在属性上,描述响应类的属性
@ApiModelProperty(value = "用户名")
private String username;
@ApiModelProperty(value = "用户地址")
private String address;
public String getUsername() {
return username;
}
public String getAddress() {
return address;
}
public void setUsername(String username) {
this.username = username;
}
public void setAddress(String address) {
this.address = address;
}
}
}
4、启动项目,输入http://localhost:8080/swagger-ui/index.html开始测试,效果图如下
接下来就可以在Swagger中开启各项API接口测试了,调试也就变得非常简单。(可以暂时告别Postman等第三方接口测试工具了)
5、补充一点,如果系统设置的有拦截,还需要排除一下Swagger3.0的相关资源,我们排除以下四种资源即可。
.excludePathPatterns("/swagger**/**") .excludePathPatterns("/webjars/**") .excludePathPatterns("/v3/**") .excludePathPatterns("/doc.html");
5、总结
全新Swagger3.0的易用性还是非常不错的,依赖相比2.0减少一个,配置更加简单,新版的页面风格更加现代化,有耳目一新的感觉。
后续我还将更新如何利用Spring Jpa/Mysql/Swagger3快速搭建一个生产级RESTFul API接口,欢迎关注、留言、转发。