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注解开启应用。

②依赖有所不同,见下文。

③访问网址不同,Swagger3http://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接口,欢迎关注、留言、转发。

Logo

为开发者提供学习成长、分享交流、生态实践、资源工具等服务,帮助开发者快速成长。

更多推荐