歡迎使用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走第二個接口