SpringBoot API版本控制

风格不统一 提交于 2021-01-30 08:57:22

欢迎使用Markdown编辑器写博客

后端开发人员经常遇到接口升级、优化接口甚至重新定义一模一样新接口而且还得兼容旧版本接口。这样我们得维护两个一模一样接口,版本管理越来越重要。基于自定义注解获得请求头Header中apiVersion参数,版本大的转发不同接口上。

RequestMappingHandlerMapping请求详情
在这里插入图片描述

  • 自定义版本注解
/**
 * @Author: LailaiMonkey
 * @Description:
 * @Date:Created in 2020-10-14 17:47
 * @Modified By:
 */
@Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface ApiVersion {
   
   

    /**
     * 版本号
     * @return
     */
    int value();
}
  • 重写RequestCondition,自定义url匹配逻辑
/**
 * @Author: LailaiMonkey
 * @Description:
 * @Date:Created in 2020-10-14 16:59
 * @Modified By:
 */
public class ApiVersionCondition implements RequestCondition<ApiVersionCondition> {
   
   

    /**
     * 版本
     */
    private int apiVersion;

    ApiVersionCondition(int apiVersion) {
   
   
        this.apiVersion = apiVersion;
    }

    /**
     * 最近优先原则,方法定义的 @ApiVersion > 请求头定义apiVersion
     *
     * @param apiVersionCondition
     * @return
     */
    @Override
    public ApiVersionCondition combine(ApiVersionCondition apiVersionCondition) {
   
   
        return new ApiVersionCondition(apiVersion);
    }

    /**
     * 获得符合匹配条件的ApiVersionCondition
     *
     * @param httpServletRequest
     * @return
     */
    @Override
    public ApiVersionCondition getMatchingCondition(HttpServletRequest httpServletRequest) {
   
   
        //获得header传递的版本号
        String apiVersion = httpServletRequest.getHeader("apiVersion");
        if (StringUtils.isNotBlank(apiVersion)) {
   
   
            try {
   
   
                Integer version = Integer.valueOf(apiVersion);
                if (version >= this.apiVersion) {
   
   
                    return this;
                }
            } catch (Exception e) {
   
   
                System.out.println("版本号不合法:{}" + apiVersion);
            }
        }
        return null;
    }

    /**
     * 优先匹配最大版本号
     *
     * @param apiVersionCondition
     * @param httpServletRequest
     * @return
     */
    @Override
    public int compareTo(ApiVersionCondition apiVersionCondition, HttpServletRequest httpServletRequest) {
   
   
        return apiVersionCondition.getApiVersion() - this.apiVersion;
    }

    private int getApiVersion() {
   
   
        return apiVersion;
    }
}
  • 重写RequestMappingHandlerMapping,自定义匹配的处理器
/**
 * @Author: LailaiMonkey
 * @Description:
 * @Date:Created in 2020-10-15 09:54
 * @Modified By:
 */
public class ApiVersioningRequestMappingHandlerMapping extends RequestMappingHandlerMapping {
   
   

    @Override
    protected RequestCondition<ApiVersionCondition> getCustomTypeCondition(Class<?> handlerType) {
   
   
        ApiVersion apiVersion = AnnotationUtils.findAnnotation(handlerType, ApiVersion.class);
        return createCondition(apiVersion);
    }

    @Override
    protected RequestCondition<ApiVersionCondition> getCustomMethodCondition(Method method) {
   
   
        ApiVersion apiVersion = AnnotationUtils.findAnnotation(method, ApiVersion.class);
        return createCondition(apiVersion);
    }

    private RequestCondition<ApiVersionCondition> createCondition(ApiVersion apiVersion) {
   
   
        return apiVersion == null ? null : new ApiVersionCondition(apiVersion.value());
    }
}
  • 配置注册自定义WebMvcRegistrations
/**
 * @Author: LailaiMonkey
 * @Description:
 * @Date:Created in 2020-10-15 09:57
 * @Modified By:
 */
@Configuration
public class WebMvcRegistrationsConfig implements WebMvcRegistrations {
   
   

    @Override
    public RequestMappingHandlerMapping getRequestMappingHandlerMapping() {
   
   
        return new ApiVersioningRequestMappingHandlerMapping();
    }
}
  • 测试Controller
	@ApiVersion(1)
    @GetMapping("/version")
    public Object version()  {
   
   
        return "version";
    }

    @ApiVersion(3)
    @GetMapping("/version")
    public Object version1()  {
   
   
        return "version1";
    }

访问localhost:8080/version且header中apiVersion为1或2走第一个接口,apiVersion大于等于3走第二个接口

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!