當(dāng)前位置:
首頁(yè) >
前端技术
> javascript
>内容正文
javascript
Spring如何实现统一的基于请求头header或url的接口版本控制
生活随笔
收集整理的這篇文章主要介紹了
Spring如何实现统一的基于请求头header或url的接口版本控制
小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.
1.基于請(qǐng)求頭方式的版本控制
定義自己的 RequestCondition 來(lái)做請(qǐng)求頭的匹配:
public class APIVersionCondition implements RequestCondition<APIVersionCondition> { ?@Getterprivate String apiVersion;@Getterprivate String headerKey; ?public APIVersionCondition(String apiVersion, String headerKey) {this.apiVersion = apiVersion;this.headerKey = headerKey;} ?@Overridepublic APIVersionCondition combine(APIVersionCondition other) {return new APIVersionCondition(other.getApiVersion(), other.getHeaderKey());} ?@Overridepublic APIVersionCondition getMatchingCondition(HttpServletRequest request) {String version = request.getHeader(headerKey);return apiVersion.equals(version) ? this : null;} ?@Overridepublic int compareTo(APIVersionCondition other, HttpServletRequest request) {return 0;} }并且自定義 RequestMappingHandlerMapping,來(lái)把方法關(guān)聯(lián)到自定義的 RequestCondition:
public class APIVersionHandlerMapping extends RequestMappingHandlerMapping {@Overrideprotected boolean isHandler(Class<?> beanType) {return AnnotatedElementUtils.hasAnnotation(beanType, Controller.class);} ?@Overrideprotected RequestCondition<APIVersionCondition> getCustomTypeCondition(Class<?> handlerType) {APIVersion apiVersion = AnnotationUtils.findAnnotation(handlerType, APIVersion.class);return createCondition(apiVersion);} ?@Overrideprotected 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(), apiVersion.headerKey());} }版本注解類
@Target({ElementType.METHOD, ElementType.TYPE}) @Retention(RetentionPolicy.RUNTIME) public @interface APIVersion {String value(); ?String headerKey() default "X-API-VERSION"; }測(cè)試Controller
@Slf4j @RequestMapping("apiversion") @RestController @APIVersion("v1") public class APIVersoinController { ?@GetMapping(value = "/api/user")public int version1() {return 1;} ?@GetMapping(value = "/api/user")@APIVersion("v2")public int version2() {return 2;} }啟動(dòng)類
@SpringBootApplication public class CommonMistakesApplication implements WebMvcRegistrations { ?public static void main(String[] args) {SpringApplication.run(CommonMistakesApplication.class, args);} ?@Overridepublic RequestMappingHandlerMapping getRequestMappingHandlerMapping() {return new APIVersionHandlerMapping();} }我們啟動(dòng)Application測(cè)試一下:
header頭中傳入v1則返回1
?
傳入v2則返回2
?
通過(guò)header頭控制版本,達(dá)到了訪問(wèn)不同controller方法的目的。
2.基于url的版本控制
APIVersionCondition.java
如果查找不到該版本,則找最高的版本
public class APIVersionCondition implements RequestCondition<APIVersionCondition> {private static final Pattern VERSION_PREFIX_PATTERN = Pattern.compile("v(\\d+)/");private int apiVersion; ?public APIVersionCondition(int apiVersion) {this.apiVersion = apiVersion;} ?public APIVersionCondition combine(APIVersionCondition other) {return new APIVersionCondition(other.getApiVersion());} ?public APIVersionCondition getMatchingCondition(HttpServletRequest request) {Matcher m = VERSION_PREFIX_PATTERN.matcher(request.getRequestURI());if (m.find()) {int version = Integer.parseInt(m.group(1));if (version >= this.apiVersion) {return this;}} ?return null;} ?public int compareTo(APIVersionCondition other, HttpServletRequest request) {return other.getApiVersion() - this.apiVersion;} ?public int getApiVersion() {return this.apiVersion;} } ?APIVersionHandlerMapping.java
public class APIVersionHandlerMapping extends RequestMappingHandlerMapping {@Overrideprotected boolean isHandler(Class<?> beanType) {return AnnotatedElementUtils.hasAnnotation(beanType, Controller.class);} ?@Overrideprotected RequestCondition<APIVersionCondition> getCustomTypeCondition(Class<?> handlerType) {APIVersion apiVersion = AnnotationUtils.findAnnotation(handlerType, APIVersion.class);return createCondition(apiVersion);} ?@Overrideprotected 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());} }APIVersion.java
@Target({ElementType.METHOD, ElementType.TYPE}) @Retention(RetentionPolicy.RUNTIME) public @interface APIVersion {int value(); }測(cè)試controller
@Slf4j @RequestMapping("{version}/apiversion") @RestController @APIVersion(1) public class APIVersoinController { ?@GetMapping(value = "/api/user")public int version1() {return 1;} ?@GetMapping(value = "/api/user")@APIVersion(2)public int version2() {return 2;} }啟動(dòng)類
@SpringBootApplication public class CommonMistakesApplication implements WebMvcRegistrations {public static void main(String[] args) {SpringApplication.run(CommonMistakesApplication.class, args);}@Overridepublic RequestMappingHandlerMapping getRequestMappingHandlerMapping() {return new APIVersionHandlerMapping();} }我們啟動(dòng)Application測(cè)試一下:
當(dāng)路徑中傳v1時(shí),會(huì)找到v1版本的方法,傳v2或者v3時(shí),會(huì)找到v2版本的方法。
總結(jié)
以上是生活随笔為你收集整理的Spring如何实现统一的基于请求头header或url的接口版本控制的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。
- 上一篇: LinkedList插入元素一定比Arr
- 下一篇: Kafka在Spring项目中的实战演练