請求路徑中增加版本號
1、定義注解:@ApiVersion
@Target({ElementType.METHOD,ElementType.TYPE}) @Retention(RetentionPolicy.RUNTIME) @Documented @Mapping public @interface ApiVersion { /** * 標識版本號 * @return */ int value(); //描述 String describe(); }
2、重寫RequestMappingHandlerMapping一些方法
public class CustomRequestMappingHandlerMapping 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()); } }
3、匹配規則版本號
public class ApiVersionCondition implements RequestCondition<ApiVersionCondition> { // 路徑中版本的前綴, 這里用 /v[1-9]/的形式 private final static Pattern VERSION_PREFIX_PATTERN = Pattern.compile("v(\\d+)/"); /** * api的版本 */ private int apiVersion; public ApiVersionCondition(int apiVersion) { this.apiVersion = apiVersion; } @Override public ApiVersionCondition combine(ApiVersionCondition apiVersionCondition) { // 采用最后定義優先原則,則方法上的定義覆蓋類上面的定義 return new ApiVersionCondition(apiVersionCondition.getApiVersion()); } /** * 根據request查找匹配到的篩選條件 */ @Override public ApiVersionCondition getMatchingCondition(HttpServletRequest httpServletRequest) { Matcher m = VERSION_PREFIX_PATTERN.matcher(httpServletRequest.getRequestURI()); if(m.find()){ Integer version = Integer.valueOf(m.group(1)); if(version >= this.apiVersion) { return this; } } return null; } /** * 不同篩選條件比較,用於排序 * @param apiVersionCondition * @param httpServletRequest * @return */ @Override public int compareTo(ApiVersionCondition apiVersionCondition, HttpServletRequest httpServletRequest) { // 優先匹配最新的版本號 return apiVersionCondition.getApiVersion() - this.apiVersion; } public int getApiVersion() { return apiVersion; } }
4、增加相應注解
@RequestMapping("{version}")
public class BaseApi1 {
@ApiVersion(value=1,describe="當前版本控制為v1")
@RequestMapping("/demo")
public String demoVersion1(){
return "version1";
}
@ApiVersion(value=2,describe="當前版本控制為v2")
@RequestMapping("/demo")
public String demoVersion2(){
return "version2";
}
}
5、請求路徑:http://localhost:8080/v1/xxxx
統一接口前綴
@Controller @RequestMapping("/v1") public class FunctionControllerA{ @RequestMapping("/functionA") public void functionA(){ //Some thing to do... } } @Controller @RequestMapping("/v1") public class FunctionControllerB{ @RequestMapping("/functionB") public void functionB(){ //Some thing to do... } }
當存在多個/v1開頭的controller且后續需要統一更改v1為v2這種,則需要改動點多,可修改為:
聲明一個統一api請求路徑接口
@RequestMapping("/v1")
public interface VersionPathAware{}
實現此接口
@Controller public class FunctionControllerA implements VersionPathAware { @RequestMapping("/functionA") public void functionA(){ //Some thing to do... } } @Controller public class FunctionControllerB implements VersionPathAware { @RequestMapping("/functionB") public void functionB(){ //Some thing to do... } }
