日韩av黄I国产麻豆传媒I国产91av视频在线观看I日韩一区二区三区在线看I美女国产在线I麻豆视频国产在线观看I成人黄色短片

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 >

Spring如何实现统一的基于请求头header或url的接口版本控制

發布時間:2025/3/20 29 豆豆
生活随笔 收集整理的這篇文章主要介紹了 Spring如何实现统一的基于请求头header或url的接口版本控制 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

1.基于請求頭方式的版本控制

定義自己的 RequestCondition 來做請求頭的匹配:

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,來把方法關聯到自定義的 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"; }

測試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;} }

啟動類

@SpringBootApplication public class CommonMistakesApplication implements WebMvcRegistrations { ?public static void main(String[] args) {SpringApplication.run(CommonMistakesApplication.class, args);} ?@Overridepublic RequestMappingHandlerMapping getRequestMappingHandlerMapping() {return new APIVersionHandlerMapping();} }

我們啟動Application測試一下:

header頭中傳入v1則返回1

?

傳入v2則返回2

?

通過header頭控制版本,達到了訪問不同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(); }

測試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;} }

啟動類

@SpringBootApplication public class CommonMistakesApplication implements WebMvcRegistrations {public static void main(String[] args) {SpringApplication.run(CommonMistakesApplication.class, args);}@Overridepublic RequestMappingHandlerMapping getRequestMappingHandlerMapping() {return new APIVersionHandlerMapping();} }

我們啟動Application測試一下:

當路徑中傳v1時,會找到v1版本的方法,傳v2或者v3時,會找到v2版本的方法。

總結

以上是生活随笔為你收集整理的Spring如何实现统一的基于请求头header或url的接口版本控制的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。