Swagger接口动态分组

本文介绍了一种基于Spring Boot和Swagger的自动化接口分组方法,通过解析映射路径实现动态分组,避免了手动配置Docket带来的不便。该方案适用于具有一定路径规律的应用场景。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

前言:网上查的接口分组,都是手动配置多个Docket来实现分组,但是这样每加一个业务还要改这里代码,太麻烦所以自己改造了一下,代码效果如下

注意:这种方式要保证接口要有一定的规则,比如(有如下三个接口1.aaa/xxx/xxx, 2.aaa/bbb/bbb,3.ccc/xx/bb)那么就会有aaa和ccc两个分组

代码:

import org.springframework.beans.factory.support.DefaultListableBeanFactory;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.method.HandlerMethod;
import org.springframework.web.servlet.mvc.condition.PatternsRequestCondition;
import org.springframework.web.servlet.mvc.method.RequestMappingInfo;
import org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerMapping;
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.Parameter;
import springfox.documentation.spi.DocumentationType;
import springfox.documentation.spring.web.plugins.Docket;
import springfox.documentation.swagger2.annotations.EnableSwagger2;

import java.util.*;

@Configuration
@EnableSwagger2
public class Swagger2Config {
    private DefaultListableBeanFactory context;
    private RequestMappingHandlerMapping mapping;


    public Swagger2Config(DefaultListableBeanFactory context, RequestMappingHandlerMapping mapping) {
        this.context = context;
        this.mapping = mapping;
        cofig();
    }

    /**
     * 执行配置
     */
    private void cofig(){
        //添加head参数配置start
        ParameterBuilder tokenPar = new ParameterBuilder();
        List<Parameter> pars = new ArrayList<Parameter>();
        tokenPar.name("Authorization").description("令牌").modelRef(new ModelRef("string")).parameterType("header").required(false).build();
        pars.add(tokenPar.build());

        Set<String> pathGroup = null;
        try {
            // 分组
            pathGroup = getPathGroup();
        } catch (ClassNotFoundException e) {
            e.printStackTrace();
        }
        // 根据分好的组,循环创建配置类并添加到容器中
        pathGroup.forEach(item -> {
            Docket enable = new Docket(DocumentationType.SWAGGER_2)
                    .apiInfo(apiInfo())
                    //是否启动swagger 如果是false则不能在浏览器中使用
                    .enable(true)
                    // 分组名称
                    .groupName(item)
                    .select()
                    // 在指定的包下,扫描注解
                    .apis(RequestHandlerSelectors.basePackage("com.hn.gege"))
                    // 过滤路劲过滤(只要指定地址开头的接口)
                    .paths(PathSelectors.ant(item + "/**"))
                    .build()
                    .globalOperationParameters(pars);//添加请求头参数;
            // 手动将配置类注入到spring bean容器中
            context.registerSingleton("enable" + item , enable);
        });

    }

    /**
     * 对接口进行分组
     * 这里就是通过spring提供的RequestMappingHandlerMapping 类拿到所有接口,然后根据最前面的接口地址进行分组
     * @return
     */
    private Set<String> getPathGroup() throws ClassNotFoundException {
        HashSet<String> set = new HashSet<>();

        Map<RequestMappingInfo, HandlerMethod> mappingHandlerMethods = mapping.getHandlerMethods();
        for (Map.Entry<RequestMappingInfo, HandlerMethod> map : mappingHandlerMethods.entrySet()) {
            HashMap<String, Object> pmap = new HashMap<>();
            RequestMappingInfo info = map.getKey();
            HandlerMethod method = map.getValue();
            PatternsRequestCondition patternsCondition = info.getPatternsCondition();
            String className = method.getMethod().getDeclaringClass().getName();
            /**
             * 匹配包路径 根据自己的路径替换
             */
            if (className.contains("com.hn.gege")) {
                for(String url : patternsCondition.getPatterns()) {
                    int i = url.indexOf("/", 1);
                    if (i<0){
                        set.add(url);
                    }else {
                        set.add(url.substring(0, i));
                    }
                }
            }
        }
        return set;
    }

private ApiInfo apiInfo() {
        return new ApiInfoBuilder()
                .title("接口文档")
                .description("项目地址:http://localhost:5200/gege")
                .version("1.0")
                .build();
    }
}

效果:在这里就可以切换不同的分组,来显示不同的接口

 

### Swagger接口分组的实现方法或配置方式 在 Swagger 文档生成工具中,接口分组是一种常见的需求,它允许开发者将 API 划分为多个逻辑模块以便更好地管理和展示。以下是关于如何在 Spring Boot 集成 Swagger 的环境中实现接口分组的具体说明。 #### 1. 开启 Swagger 功能 首先需要确保 Swagger 已经正确集成到项目中,并且可以通过配置文件启用其功能。例如,在 `application.yml` 文件中设置以下属性来控制 Swagger 是否开启: ```yaml springfox: documentation: enabled: true ``` 此部分配置决定了 Swagger UI 页面是否会加载以及相关文档是否会被构建[^1]。 #### 2. 创建不同的 Docket 实例 为了支持多组 API 文档,需创建多个 `Docket` 对象实例,每个对象代表一组独立的 API 定义。下面给出了一种典型的 Java 配置类写法示例: ```java import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import springfox.documentation.builders.PathSelectors; import springfox.documentation.spi.DocumentationType; import springfox.documentation.spring.web.plugins.Docket; @Configuration public class SwaggerConfig { @Bean public Docket dockBase() { return new Docket(DocumentationType.SWAGGER_2) .groupName("base-group") // 设置当前分组名称 .select() .paths(PathSelectors.ant("/api/**")) // 只扫描 /api 下面的接口 .build(); } @Bean public Docket docketDemo2() { return new Docket(DocumentationType.SWAGGER_2) .groupName("demo2-group") // 设置另一个分组名称 .select() .paths(PathSelectors.regex("/test.*")) // 自定义正则表达式筛选路径 .build(); } } ``` 在此代码片段中展示了两种不同规则下的分组策略:一种基于固定的前缀匹配 (`/api/**`) ,另一种则是灵活运用了正则模式识别特定 URL 模式的资源[^2]。 #### 3. 使用 RequestHandler 进行更精细的过滤 除了简单的路径匹配外,还可以借助 `Predicate<RequestHandler>` 来进一步细化哪些请求应该归属于某个具体的分组之下。比如可以根据控制器上的自定义注解来进行分类: ```java @Bean public Docket customGroupedApis() { Predicate<RequestHandler> predicate = input -> { Api apiAnnotation = AnnotationUtils.findAnnotation(input.declaringClass(), Api.class); if (apiAnnotation != null && "custom".equals(apiAnnotation.tags()[0])) { return true; } else { return false; } }; return new Docket(DocumentationType.SWAGGER_2) .groupName("custom-tagged-apis") .apis(predicate) .paths(PathSelectors.any()) .build(); } ``` 这里我们通过判断 Controller 类是否存在名为 `"custom"` tag 的 `@Api` 注解决定将其加入至 “custom-tagged-apis” 组合之中[^3]。 --- 以上就是有关于如何在 Swagger 当中完成对接口进行有效分组的一些常见做法介绍。每种方案都有各自适用场景,请根据实际业务需求选取最合适的方式实施部署。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值