①在前后端分离开发中,一般需要构建一份API文档来描述所有接口信息,文档工作量巨大,需要包含接口地址、请求参数以及返回值等,且维护不方便,一旦接口发生变化就需要修改文档。
②Swagger的出现可以帮助开发人员快速设计、构建、记录、使用RESTFul API/Web服务。它将代码和文档融为一体,完美解决上述问题,将开发人员的精力集中到业务中,而不是繁琐的文档。
③网上很多Swagger教程均基于Swagger2,现均已过时,而本文将带来全新Swagger3.0教程,以最简单的方式实现Swagger3(OAS3)快速配置上手,实现API接口文档自动化。
JAVA11或者JAVA13
Spring-boot 2.5+
①Swagger3通过@EnableOpenApi注解开启应用,而Swagger2通过@EnableSwagger2注解开启应用。
②依赖有所不同,见下文。
③访问网址不同,Swagger3是http://localhost:8080/swagger-ui/index.html,Swagger2是http://localhost:8080/swagger-ui.html,这个要特别注意。
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");
全新Swagger3.0的易用性还是非常不错的,依赖相比2.0减少一个,配置更加简单,新版的页面风格更加现代化,有耳目一新的感觉。
后续我还将更新如何利用Spring Jpa/Mysql/Swagger3快速搭建一个生产级RESTFul API接口,欢迎关注、留言、转发。