【Swagger2源码级教学】03扫描接口

上节我们初步了解Docket,接下来我们继续了解Docket内的配置方法。

select(),selector()方法

在这里插入图片描述

​ 这两个方法实现了扫描项目中接口的功能。其中select()方法是行为,selector() 是行为的发起者,行为被委托给ApiSelectorBuilder对象去具体实现,当行为完成后,ApiSelectorBuilder将行为的结果返回给行为的发起者selector()

在这里插入图片描述

​ 注释翻译为:

*启动用于api选择的生成器。
    

*@return api选择生成器。要完成构建api选择器,请使用api选择器的构建方法需要调用,这将在调用build方法时自动返回到构建摘要。

*/
ApiSelectorBuilder(接口选择器构建者)
apis() 方法

​ 该对象是扫描接口的执行者,调用apis() 方法 完成行为,调用build()方法将行为结果返回给行为的发起者selector()selector() 返回Docket实例,使得结果最后归于Docket。

在这里插入图片描述

apis()方法的参数决定如何扫描我们的接口,apis()方法提供了5种扫描方式,分别如下:

  • 1、RequestHandlerSelectors.none() 不匹配任何controller的接口
  • 2、RequestHandlerSelectors.any() 匹配任何controller的接口
  • 3、RequestHandlerSelectors.withClassAnnotation() 扫描含有类注解的 参数为 注解名+ .class
  • 4、RequestHandlerSelectors.withMethodAnnotation() 扫描含有方法注解的 参数为 注解名+ .class
  • 5、RequestHandlerSelectors.basePackage() 扫描指定包路径 参数为 包路径的字符串

以第一种为例,代码如下:

import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import springfox.documentation.builders.RequestHandlerSelectors;
import springfox.documentation.service.ApiInfo;
import springfox.documentation.service.Contact;
import springfox.documentation.spi.DocumentationType;
import springfox.documentation.spring.web.plugins.Docket;
import springfox.documentation.swagger2.annotations.EnableSwagger2;

import java.util.ArrayList;

/**
 * TODO
 *
 * @author ben
 * @version 1.0
 * @date 2022/9/13 11:23
 */
@Configuration
@EnableSwagger2
public class SwaggerConfig {
    @Bean
    public Docket docket() {
        return new Docket(DocumentationType.SWAGGER_2)
                .apiInfo(apiInfo())
                .select()
                .apis(RequestHandlerSelectors.none())
                .build();
    }

    //配置文档信息
    private ApiInfo apiInfo() {
        Contact contact = new Contact("ben", "https://xxxxxx.com", "Swagger2Config@SpringBoot.com");
        return new ApiInfo(
                "Ben的学习总结", // 标题
                "Swagger2Config", // 描述
                "v1.0", // 版本
                "https://xxxxxx.com", // 组织链接
                contact, // 联系人信息
                "Apach 2.0 许可", // 许可
                "https://xxxxxx.com", // 许可连接
                new ArrayList<>()// 扩展
        );
    }
}

启动看一看:

在这里插入图片描述

之前:
在这里插入图片描述

​ 我在controller层新建了两个接口:

在这里插入图片描述

​ 扫描包路径:

import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import springfox.documentation.builders.RequestHandlerSelectors;
import springfox.documentation.service.ApiInfo;
import springfox.documentation.service.Contact;
import springfox.documentation.spi.DocumentationType;
import springfox.documentation.spring.web.plugins.Docket;
import springfox.documentation.swagger2.annotations.EnableSwagger2;

import java.util.ArrayList;

/**
 * TODO
 *
 * @author ben
 * @version 1.0
 * @date 2022/9/13 11:23
 */
@Configuration
@EnableSwagger2
public class SwaggerConfig {
    @Bean
    public Docket docket() {
        return new Docket(DocumentationType.SWAGGER_2)
                //配置文档信息
                .apiInfo(apiInfo())
                //扫描行为
                .select()
                //接口扫描 不匹配任何controller的接口
                // .apis(RequestHandlerSelectors.none())
                //扫描指定包路径  参数为 包路径的字符串
                .apis(RequestHandlerSelectors.basePackage("cn.ben.swagger2config.controller"))
                .build();
    }

    //配置文档信息
    private ApiInfo apiInfo() {
        Contact contact = new Contact("ben", "https://xxxxxx.com", "Swagger2Config@SpringBoot.com");
        return new ApiInfo(
                "Ben的学习总结", // 标题
                "Swagger2Config", // 描述
                "v1.0", // 版本
                "https://xxxxxx.com", // 组织链接
                contact, // 联系人信息
                "Apach 2.0 许可", // 许可
                "https://xxxxxx.com", // 许可连接
                new ArrayList<>()// 扩展
        );
    }
}

启动后:

在这里插入图片描述

apis()的运用
@Bean
public Docket createRestApi() {
    return new Docket(DocumentationType.SWAGGER_2)
            .apiInfo(apiInfo())
            .select()
            .apis(RequestHandlerSelectors.basePackage("com.fan.controller"))
            .apis(RequestHandlerSelectors.withClassAnnotation(Api.class))
            .build().globalOperationParameters(defaultHeader());
}

​ 如上代码,在apis()方法中可以进行配置扫描条件,可以通过apis()进行多次设置,apis方法参数为Predicate<RequestHandler> selector

// apis方法源码
public ApiSelectorBuilder apis(Predicate<RequestHandler> selector) {
    this.requestHandlerSelector = Predicates.and(this.requestHandlerSelector, selector);
    return this;
}

​ 查看apis()方法的源码可以发现,条件参数selector被Predicates以and()方法操作,并返回一个Predicate<RequestHandler>类,Predicates.and()实际上完成"条件1 and 条件2"的操作,类似于sql语句where条件的内容,根据这个特点,可以通过Predicates.and()Predicates.or()的方法完成"(条件1 and 条件2) or 条件3"的操作,就可以扫描任何指定包下的API,并实现多路径扫描、交集、并集等配置。swagger示例如下:

import com.google.common.base.Predicate;
import com.google.common.base.Predicates;
import io.swagger.annotations.ApiOperation;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.servlet.config.annotation.EnableWebMvc;
import springfox.documentation.RequestHandler;
import springfox.documentation.builders.ApiInfoBuilder;
import springfox.documentation.builders.ParameterBuilder;
import springfox.documentation.builders.PathSelectors;
import springfox.documentation.builders.RequestHandlerSelectors;
import springfox.documentation.schema.ModelRef;
import springfox.documentation.service.ApiInfo;
import springfox.documentation.service.Contact;
import springfox.documentation.service.Parameter;
import springfox.documentation.spi.DocumentationType;
import springfox.documentation.spring.web.plugins.Docket;
import springfox.documentation.swagger2.annotations.EnableSwagger2;

import java.util.ArrayList;
import java.util.List;

@EnableSwagger2
@Configuration
public class SwaggerConfig {
 
    @Bean
    public Docket createRestApi() {
        return new Docket(DocumentationType.SWAGGER_2)
                .apiInfo(apiInfo())
                .select()
                .apis(getBasePackages())
                .build();
    }

    // 设置多路径
    private Predicate<RequestHandler> getBasePackages() {
        Predicate<RequestHandler> predicate = Predicates.and(RequestHandlerSelectors.basePackage("cn.ben.for_learn_projects.swagger2config.controller"));  // 扫描cn.ben.for_learn_projects.swagger2config.controller包
        predicate = Predicates.and(RequestHandlerSelectors.withMethodAnnotation(ApiOperation.class), predicate) // 扫描cn.ben.for_learn_projects.swagger2config.controller包下有@ApiOperation,和上面是交集
        predicate = Predicates.or(RequestHandlerSelectors.basePackage("cn.ben.for_learn_projects.swagger2config.controller2"), predicate)// 扫描cn.ben.for_learn_projects.swagger2config.controller2包,和上面是并集
        return predicate;
    }


    private ApiInfo apiInfo() {
        return new ApiInfoBuilder()
                .title("后台API接口文档")
                .description("后台API接口文档")
                .termsOfServiceUrl("")
                .contact(new Contact("", "", "1663501@qq.com")) 
                .version("V 1.0.0")
                .build();
    }
}
paths() 方法

​ 在 ApiSelectorBuilder对象中,通过apis()方法扫描接口,通过paths()方法过滤接口。

在这里插入图片描述

path()方法接收一个 PathSelectors 对象

在这里插入图片描述

该对象有四个方法,对应四种过滤方式:

  • any() // 任何请求都扫描

  • none() // 任何请求都不扫描

  • regex(final String pathRegex) // 通过正则表达式控制

      @Bean
        public Docket docket(){
            return new Docket(DocumentationType.SWAGGER_2)
                    .apiInfo(apiInfo())
                    .select()
                    .paths(PathSelectors.regex("^[+-@=](.*?)"))//该正则表示匹配所有
                    .build();
        }
    
    
  • ant(final String antPattern) // 通过ant()控制

    @Bean
        public Docket docket(){
            return new Docket(DocumentationType.SWAGGER_2)
                    .apiInfo(apiInfo())
                    .select()
                    .paths(PathSelectors.ant("/test-swagger2/**"))//匹配/test-swagger2/开头的所有controller
                    .build();
        }
    
    

apis()paths() 一起使用时,代码如下:

import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import springfox.documentation.builders.PathSelectors;
import springfox.documentation.builders.RequestHandlerSelectors;
import springfox.documentation.service.ApiInfo;
import springfox.documentation.service.Contact;
import springfox.documentation.spi.DocumentationType;
import springfox.documentation.spring.web.plugins.Docket;
import springfox.documentation.swagger2.annotations.EnableSwagger2;

import java.util.ArrayList;

/**
 * TODO
 *
 * @author ben
 * @version 1.0
 * @date 2022/9/13 11:23
 */
@Configuration
@EnableSwagger2
public class SwaggerConfig {
    @Bean
    public Docket docket() {
        return new Docket(DocumentationType.SWAGGER_2)
                //配置文档信息
                .apiInfo(apiInfo())
                //扫描行为
                .select()
                //接口扫描 不匹配任何controller的接口
                // .apis(RequestHandlerSelectors.none())
                //扫描指定包路径  参数为 包路径的字符串
                .apis(RequestHandlerSelectors.basePackage("cn.ben.for_learn_projects.swagger2config.controller"))
                /// 任何请求都扫描
                .paths(PathSelectors.any())
                .build();
    }

    //配置文档信息
    private ApiInfo apiInfo() {
        Contact contact = new Contact("ben", "https://xxxxxx.com", "Swagger2Config@SpringBoot.com");
        return new ApiInfo(
                "Ben的学习总结", // 标题
                "Swagger2Config", // 描述
                "v1.0", // 版本
                "https://xxxxxx.com", // 组织链接
                contact, // 联系人信息
                "Apach 2.0 许可", // 许可
                "https://xxxxxx.com", // 许可连接
                new ArrayList<>()// 扩展
        );
    }
}
小结

​ Docket内有select()方法将扫描行为委托给ApiSelectorBuilder对象,ApiSelectorBuilder通过apis()方法扫描接口,通过 paths()方法过滤接口,最后通过build()方法将扫描行为的结果返回selecteor(),将行为的结果带回Docket。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值