springboot整合Swagger2,实现对接口的版本管理

springboot整合Swagger2,实现对接口的版本管理

1. 需求

测试同学有需求,对于接口,之前的版本是1.0,现在是1.1版本,我想要知道1.1新增了什么接口,或者说修改了什么接口,怎么办?

2. 细化需求

我们用分组来实现,分组在代码里就是 Docket,如图

在这里插入图片描述

  • 我们希望有一个默认的分组,所有的接口都放在这里,并且是排在最前面的
  • 被标记的接口能归类到 v2.7.3里
  • 一个接口可以同时被归类到多个地方,比如同时属于默认、v2.7.3、v2.8
  • 用于标记的注解,可以放在方法上,相当于全部接口都标注了;有可以单独标注在某个方法;标注在方法具有较高的优先级

3. 如何实现

3.1 如何共存多套UI

其实是可以共存多个UI的,实际测试可行。注意有时候会发现其中一个UI能刷出来另外一个不行,可以稍微等一等再试,或者调换下一下两个UI的顺序再试下。总之我遇到过 “其中一个UI可以另外一个不行” 的情况,但是最终发现 “两个UI可以并存”

3.2 步骤
  1. 新建springboot项目,或者在已有项目,在pom.xml中增加

    <!-- Swagger2 BEGIN -->
    <!--
    swagger2包中swagger-models版本有bug,example为空串会爆出NumberFormatException,需要排除并引入高版本
    排除时将 swagger-models 和 swagger-annotations 整一对排除
    -->
    <dependency>
      <groupId>io.springfox</groupId>
      <artifactId>springfox-swagger2</artifactId>
      <version>2.9.2</version>
      <exclusions>
        <exclusion>
          <groupId>io.swagger</groupId>
          <artifactId>swagger-models</artifactId>
        </exclusion>
        <exclusion>
          <groupId>io.swagger</groupId>
          <artifactId>swagger-annotations</artifactId>
        </exclusion>
      </exclusions>
    </dependency>
    <dependency>
      <groupId>io.swagger</groupId>
      <artifactId>swagger-models</artifactId>
      <version>1.6.0</version>
    </dependency>
    <dependency>
      <groupId>io.swagger</groupId>
      <artifactId>swagger-annotations</artifactId>
      <version>1.6.0</version>
    </dependency>
    
    <!-- 不满意可以注释掉换其他UI,可以同时开启多个UI -->
    <!-- 官方UI,请求路径 http://{host}:{port}/swagger-ui.html -->
    <dependency>
      <groupId>io.springfox</groupId>
      <artifactId>springfox-swagger-ui</artifactId>
      <version>2.9.2</version>
    </dependency>
    
    
    <!-- bootstrap-ui,请求路径:http://{host}:{port}/doc.html,觉得是最好的UI -->
    <!--<dependency>
          <groupId>com.github.xiaoymin</groupId>
          <artifactId>swagger-bootstrap-ui</artifactId>
          <version>1.9.6</version>
    </dependency>-->
    
    
    <!-- ui-layer,请求路径:http://{host}:{port}/docs.html,觉得没比原生的好 -->
    <!--<dependency>
          <groupId>com.github.caspar-chen</groupId>
            <artifactId>swagger-ui-layer</artifactId>
            <version>1.1.3</version>
    </dependency>-->
    <!-- Swagger2 END -->
    
  2. 写一个注解,用于标注

    @Retention(RetentionPolicy.RUNTIME)
    @Target({ElementType.METHOD, ElementType.TYPE})
    public @interface ApiVersion {
        /**
         * 分组名(即版本号),可以传入多个
         *
         * @return
         */
        String[] value();
    }
    
  3. 写一个版本常量类,有新版本就在这里加

    public interface ApiVersionConstant {
        String VERSION_2_7_3 = "v2.7.3";
        String VERSION_2_8 = "v2.8";
    }
    
  4. 写Swagger的配置类

    package com.wyf.test.swagger2springboot.config.swagger;
    
    import org.springframework.beans.factory.InitializingBean;
    import org.springframework.beans.factory.annotation.Autowired;
    import org.springframework.beans.factory.config.AutowireCapableBeanFactory;
    import org.springframework.beans.factory.support.AbstractBeanDefinition;
    import org.springframework.beans.factory.support.BeanDefinitionBuilder;
    import org.springframework.beans.factory.support.DefaultListableBeanFactory;
    import org.springframework.context.ApplicationContext;
    import org.springframework.context.annotation.Bean;
    import org.springframework.context.annotation.Configuration;
    import springfox.documentation.builders.ApiInfoBuilder;
    import springfox.documentation.builders.PathSelectors;
    import springfox.documentation.builders.RequestHandlerSelectors;
    import springfox.documentation.service.ApiInfo;
    import springfox.documentation.spi.DocumentationType;
    import springfox.documentation.spring.web.plugins.Docket;
    import springfox.documentation.swagger2.annotations.EnableSwagger2;
    
    import java.lang.reflect.Field;
    import java.util.Arrays;
    
    /**
     * Swagger配置
     *
     * @author Stone
     * @version V1.0.0
     * @date 2020/3/12
     */
    @Configuration
    @EnableSwagger2
    public class Swagger2Config implements InitializingBean {
    
        @Autowired
        private ApplicationContext applicationContext;
    
        // 默认版本的分组
        @Bean
        public Docket docket() {
            // basePackage 需要扫描注解生成文档的路径
            return new Docket(DocumentationType.SWAGGER_2)
                    // 分组名用aaa开头以便排在最前面
                    .groupName("aaa_默认分组(所有接口)")
                    .apiInfo(apiInfo())
                    .select()
                    .apis(RequestHandlerSelectors.basePackage("com.wyf.test.swagger2springboot"))
                    .paths(PathSelectors.any())
                    .build();
        }
    
        private ApiInfo apiInfo() {
            return new ApiInfoBuilder()
                    .title("Swagger demo")
                    .description("这是展示Swagger怎么用的例子")
                    .version("1.0").build();
        }
    
        private Docket buildDocket(String groupName) {
            return new Docket(DocumentationType.SWAGGER_2)
                    .apiInfo(apiInfo())
                    .groupName(groupName)
                    .select()
                    .apis(method -> {
                        // 每个方法会进入这里进行判断并归类到不同分组,**请不要调换下面两段代码的顺序,在方法上的注解有优先级**
    
                        // 该方法上标注了版本
                        if (method.isAnnotatedWith(ApiVersion.class)) {
                            ApiVersion apiVersion = method.getHandlerMethod().getMethodAnnotation(ApiVersion.class);
                            if (apiVersion.value() != null && apiVersion.value().length != 0) {
                                if (Arrays.asList(apiVersion.value()).contains(groupName)) {
                                    return true;
                                }
                            }
    
                        }
    
                        // 方法所在的类是否标注了?
                        ApiVersion annotationOnClass = method.getHandlerMethod().getBeanType().getAnnotation(ApiVersion.class);
                        if (annotationOnClass != null) {
                            if (annotationOnClass.value() != null && annotationOnClass.value().length != 0) {
                                if (Arrays.asList(annotationOnClass.value()).contains(groupName)) {
                                    return true;
                                }
                            }
                        }
                        return false;
                    })
                    .paths(PathSelectors.any())
                    .build();
        }
    
        /**
         * 动态得创建Docket bean
         *
         * @throws Exception
         */
        @Override
        public void afterPropertiesSet() throws Exception {
            // ApiConstantVersion 里面定义的每个变量会成为一个docket
            Class<ApiVersionConstant> clazz = ApiVersionConstant.class;
            Field[] declaredFields = clazz.getDeclaredFields();
    
            // 动态注入bean
            AutowireCapableBeanFactory autowireCapableBeanFactory = applicationContext.getAutowireCapableBeanFactory();
            if (autowireCapableBeanFactory instanceof DefaultListableBeanFactory) {
                DefaultListableBeanFactory capableBeanFactory = (DefaultListableBeanFactory) autowireCapableBeanFactory;
                for (Field declaredField : declaredFields) {
    
                    // 要注意 "工厂名和方法名",意思是用这个bean的指定方法创建docket
                    AbstractBeanDefinition beanDefinition = BeanDefinitionBuilder
                            .genericBeanDefinition()
                            .setFactoryMethodOnBean("buildDocket", "swagger2Config")
                            .addConstructorArgValue(declaredField.get(ApiVersionConstant.class)).getBeanDefinition();
                    capableBeanFactory.registerBeanDefinition(declaredField.getName(), beanDefinition);
                }
            }
        }
    }
    
  5. 需要放在特别的分组的方法,用@ApiVersion标记,如

    // 放在方法上,可以有多个版本
    @ApiOperation("新增订单")
    @PostMapping("/order/add2")
    @ApiVersion({ApiVersionConstant.VERSION_2_7_3, ApiVersionConstant.VERSION_2_8})
    public ResponseDTO<OrderRespDTO> addOrder2(
      @ApiParam(value = "订单信息", required = true) @Valid OrderReqDTO orderReqDTO
    )
      
      
    // 放在类上,则所有接口都生效
    @RestController
    @Api(tags = "用户模块")
    @ApiVersion(ApiVersionConstant.VERSION_2_7_3)
    public class UserController {
      ...
    }
    
  6. 效果,切换分组仅显示分组所包含的接口

    在这里插入图片描述

  • 2
    点赞
  • 11
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
实现springboot整合swagger2 3.0.0版本,你需要按照以下步骤操作: 1. 创建一个maven项目并引入spring-boot-starter-web和springfox-boot-starter依赖。在pom.xml文件中添加以下代码: ```xml <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-web</artifactId> <!-- <version>2.5.6</version> --> <!-- <version>2.6.3</version> --> <!-- <version>2.6.5</version> --> <version>2.7.3</version> </dependency> <dependency> <groupId>io.springfox</groupId> <artifactId>springfox-boot-starter</artifactId> <version>3.0.0</version> </dependency> <dependency> <groupId>org.projectlombok</groupId> <artifactId>lombok</artifactId> <version>1.18.26</version> </dependency> ``` 2. 在application.yml配置文件中添加以下内容: ```yaml spring: mvc: pathmatch: matching-strategy: ant_path_matcher ``` 3. 创建启动类,并在其中添加`@EnableSwagger2`注解。例如: ```java @SpringBootApplication @EnableSwagger2 public class YourApplication { public static void main(String[] args) { SpringApplication.run(YourApplication.class, args); } } ``` 这样就完成了springboot整合swagger2 3.0.0版本的配置。你可以根据需要在项目中编写相应的接口文档注解以及其他相关配置。如果需要更详细的操作步骤和示例代码,你可以参考中提供的链接。<span class="em">1</span><span class="em">2</span><span class="em">3</span> #### 引用[.reference_title] - *1* *2* [Springboot整合Swagger2(3.0.0版本)](https://blog.csdn.net/mo_sss/article/details/130820204)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v93^chatsearchT3_2"}}] [.reference_item style="max-width: 50%"] - *3* [Springboot整合Swagger UI 3.0.0 版本](https://blog.csdn.net/qq_42102911/article/details/126410050)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v93^chatsearchT3_2"}}] [.reference_item style="max-width: 50%"] [ .reference_list ]

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值