欢迎使用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走第二个接口
来源:oschina
链接:https://my.oschina.net/u/4398140/blog/4938153