日本不卡不码高清免费观看,久久国产精品久久w女人spa,黄色aa久久,三上悠亚国产精品一区二区三区

您的位置:首頁技術文章
文章詳情頁

SpringBoot實現(xiàn)API接口的完整代碼

瀏覽:44日期:2023-04-14 13:40:13

一、簡介

產(chǎn)品迭代過程中,同一個接口可能同時存在多個版本,不同版本的接口URL、參數(shù)相同,可能就是內(nèi)部邏輯不同。尤其是在同一接口需要同時支持舊版本和新版本的情況下,比如APP發(fā)布新版本了,有的用戶可能不選擇升級,這是后接口的版本管理就十分必要了,根據(jù)APP的版本就可以提供不同版本的接口。

二、代碼實現(xiàn)

本文的代碼實現(xiàn)基于SpringBoot 2.3.4-release

1.定義注解

ApiVersion

@Target({ElementType.TYPE, ElementType.METHOD})@Retention(RetentionPolicy.RUNTIME)@Documentedpublic @interface ApiVersion { /** * 版本。x.y.z格式 * * @return */ String value() default '1.0.0';}

value值默認為1.0.0

EnableApiVersion

/** * 是否開啟API版本控制 */@Target(ElementType.TYPE)@Documented@Retention(RetentionPolicy.RUNTIME)@Import(ApiAutoConfiguration.class)public @interface EnableApiVersion {}

在啟動類上添加這個注解后就可以開啟接口的多版本支持。使用Import引入配置ApiAutoConfiguration。

2.將版本號抽象為ApiItem類

ApiItem

@Datapublic class ApiItem implements Comparable<ApiItem> { private int high = 1; private int mid = 0; private int low = 0; public static final ApiItem API_ITEM_DEFAULT = ApiConverter.convert(ApiVersionConstant.DEFAULT_VERSION); public ApiItem() { } @Override public int compareTo(ApiItem right) { if (this.getHigh() > right.getHigh()) { return 1; } else if (this.getHigh() < right.getHigh()) { return -1; } if (this.getMid() > right.getMid()) { return 1; } else if (this.getMid() < right.getMid()) { return -1; } if (this.getLow() > right.getLow()) { return 1; } else if (this.getLow() < right.getLow()) { return -1; }return 0; }}

為了比較版本號的大小,實現(xiàn)Comparable接口并重寫compareTo(),從高位到低位依次比較。

ApiConverter

public class ApiConverter { public static ApiItem convert(String api) { ApiItem apiItem = new ApiItem(); if (StringUtils.isBlank(api)) { return apiItem; } String[] cells = StringUtils.split(api, '.'); apiItem.setHigh(Integer.parseInt(cells[0])); if (cells.length > 1) { apiItem.setMid(Integer.parseInt(cells[1])); } if (cells.length > 2) { apiItem.setLow(Integer.parseInt(cells[2])); }return apiItem; }}

ApiConverter提供靜態(tài)方法將字符創(chuàng)轉(zhuǎn)為ApiItem。

常量類,定義請求頭及默認版本號

public class ApiVersionConstant { /** * header 指定版本號請求頭 */ public static final String API_VERSION = 'x-api-version'; /** * 默認版本號 */ public static final String DEFAULT_VERSION = '1.0.0';}

3.核心ApiCondition

新建ApiCondition類,實現(xiàn)RequestCondition,重寫combine、getMatchingCondition、compareTo方法。

RequestCondition

public interface RequestCondition<T> { /** * 方法和類上都存在相同的條件時的處理方法 */ T combine(T other); /** * 判斷是否符合當前請求,返回null表示不符合 */ @Nullable T getMatchingCondition(HttpServletRequest request); /** *如果存在多個符合條件的接口,則會根據(jù)這個來排序,然后用集合的第一個元素來處理 */ int compareTo(T other, HttpServletRequest request);

以上對RequestCondition簡要說明,后續(xù)詳細源碼分析各個方法的作用。

ApiCondition

@Slf4jpublic class ApiCondition implements RequestCondition<ApiCondition> { public static ApiCondition empty = new ApiCondition(ApiConverter.convert(ApiVersionConstant.DEFAULT_VERSION)); private ApiItem version; private boolean NULL; public ApiCondition(ApiItem item) { this.version = item; } public ApiCondition(ApiItem item, boolean NULL) { this.version = item; this.NULL = NULL; } /** * <pre> * Spring先掃描方法再掃描類,然后調(diào)用{@link #combine} * 按照方法上的注解優(yōu)先級大于類上注解的原則處理,但是要注意如果方法上不定義注解的情況。 * 如果方法或者類上不定義注解,我們會給一個默認的值{@code empty},{@link ApiHandlerMapping} * </pre> * @param other 方法掃描封裝結(jié)果 * @return */ @Override public ApiCondition combine(ApiCondition other) { // 選擇版本最大的接口 if (other.NULL) { return this; } return other; } @Override public ApiCondition getMatchingCondition(HttpServletRequest request) { if (CorsUtils.isPreFlightRequest(request)) { return empty; } String version = request.getHeader(ApiVersionConstant.API_VERSION); // 獲取所有小于等于版本的接口;如果前端不指定版本號,則默認請求1.0.0版本的接口 if (StringUtils.isBlank(version)) { log.warn('未指定版本,使用默認1.0.0版本。'); version = ApiVersionConstant.DEFAULT_VERSION; } ApiItem item = ApiConverter.convert(version); if (item.compareTo(ApiItem.API_ITEM_DEFAULT) < 0) { throw new IllegalArgumentException(String.format('API版本[%s]錯誤,最低版本[%s]', version, ApiVersionConstant.DEFAULT_VERSION)); } if (item.compareTo(this.version) >= 0) { return this; } return null; } @Override public int compareTo(ApiCondition other, HttpServletRequest request) { // 獲取到多個符合條件的接口后,會按照這個排序,然后get(0)獲取最大版本對應的接口.自定義條件會最后比較 int compare = other.version.compareTo(this.version); if (compare == 0) { log.warn('RequestMappingInfo相同,請檢查!version:{}', other.version); } return compare; }}

3.配置類注入容器

ApiHandlerMapping

public class ApiHandlerMapping extends RequestMappingHandlerMapping { @Override protected RequestCondition<?> getCustomTypeCondition(Class<?> handlerType) { return buildFrom(AnnotationUtils.findAnnotation(handlerType, ApiVersion.class)); } @Override protected RequestCondition<?> getCustomMethodCondition(Method method) { return buildFrom(AnnotationUtils.findAnnotation(method, ApiVersion.class)); } private ApiCondition buildFrom(ApiVersion platform) { return platform == null ? getDefaultCondition() :new ApiCondition(ApiConverter.convert(platform.value())); } private ApiCondition getDefaultCondition(){ return new ApiCondition(ApiConverter.convert(ApiVersionConstant.DEFAULT_VERSION),true); }}

ApiAutoConfiguration

public class ApiAutoConfiguration implements WebMvcRegistrations { @Override public RequestMappingHandlerMapping getRequestMappingHandlerMapping() { return new ApiHandlerMapping(); }}

ApiAutoConfiguration沒有使用Configuration自動注入,而是使用Import帶入,目的是可以在程序中選擇性啟用或者不啟用版本控制。

三、原理解析

四、總結(jié)

到此這篇關于SpringBoot實現(xiàn)API接口的文章就介紹到這了,更多相關SpringBoot實現(xiàn)API接口內(nèi)容請搜索好吧啦網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關文章希望大家以后多多支持好吧啦網(wǎng)!

標簽: Spring
相關文章:
日本不卡不码高清免费观看,久久国产精品久久w女人spa,黄色aa久久,三上悠亚国产精品一区二区三区
女人av一区| 亚洲一本视频| 日韩av三区| 亚洲精品精选| 中文字幕在线看片| 黄色日韩在线| 国产日韩免费| 欧美天堂一区| 欧美日韩免费观看视频| 日韩av有码| 亚洲综合三区| 精品午夜久久| 国产一区二区三区国产精品| 国产主播一区| 伊人久久成人| 久久精品伊人| 福利一区和二区| www.51av欧美视频| 日本少妇一区| 99re国产精品| 精品中文字幕一区二区三区四区| 国产午夜一区| 国产精品115| 亚洲国产一区二区在线观看| 亚洲欧美日本视频在线观看| 国产精品nxnn| 免费成人网www| 丝袜美腿成人在线| 成人日韩在线观看| 亚洲一区网站| 给我免费播放日韩视频| 四虎4545www国产精品| 欧美久久香蕉| 99久精品视频在线观看视频| 亚洲高清成人| 国产精品亚洲二区| 日韩精品诱惑一区?区三区| 中文字幕亚洲影视| 国产欧美日韩亚洲一区二区三区| 国产欧美日韩亚洲一区二区三区| 午夜一级久久| 欧美日韩18| 亚洲欧美日韩精品一区二区| 国产调教精品| 亚洲久久一区| 一区三区视频| 国产欧美激情| 亚洲三级av| 精品淫伦v久久水蜜桃| 亚洲精品九九| 99日韩精品| 日韩免费看片| 老司机精品视频网| 伊人精品久久| 日本免费新一区视频| 成人久久一区| 日韩影院二区| 亚洲专区视频| 视频一区二区欧美| 老司机精品视频在线播放| 日韩高清不卡在线| 国产美女精品视频免费播放软件| 综合精品一区| 欧美不卡视频| 国产极品模特精品一二| 日韩精品国产欧美| 国产 日韩 欧美一区| 国产成人调教视频在线观看| 亚洲午夜一级| 99国产精品视频免费观看一公开 | 亚洲综合二区| 精品久久亚洲| 精品欧美日韩精品| 亚洲区第一页| 成人国产精品一区二区网站| 国产精品对白| 亚洲精品美女91| 亚洲青青久久| 欧美日中文字幕| 悠悠资源网久久精品| 青青在线精品| 午夜精品网站| 日韩中文欧美在线| 色综合www| 99成人在线视频| 免费一区二区三区在线视频| 久久av影视| 国产一区成人| 国产精品最新| 蜜桃av一区二区| 亚洲女同av| 久久国产影院| 国产亚洲一级| 日本亚洲不卡| 国产精品xvideos88| 久久99高清| 中文在线资源| 亚洲手机视频| 蜜臀av一区二区在线免费观看| 日韩 欧美一区二区三区| 欧美日韩国产高清电影| 亚洲一区网站| 久久一区二区中文字幕| 美国三级日本三级久久99| 五月激情久久| 黑丝一区二区三区| 国产一区二区视频在线看| 国产欧美日韩一区二区三区四区| av不卡在线看| 天堂精品久久久久| 国产亚洲一区在线| 999久久久91| 日韩在线不卡| 裤袜国产欧美精品一区| 国产无遮挡裸体免费久久| 中文av在线全新| 亚洲在线观看| 久久av国产紧身裤| 久久国产中文字幕| 在线一区免费| 国产日韩欧美三区| 久久在线免费| 99精品在线免费在线观看| 日韩专区一卡二卡| 老司机精品久久| 免费观看亚洲天堂| 国产激情久久| 精品欧美激情在线观看| 久久高清免费| 日韩中文字幕区一区有砖一区| 狠狠色狠狠色综合日日tαg| 日韩精品中文字幕吗一区二区| 日本亚洲最大的色成网站www| 国产精品久久久久蜜臀| 国产精选久久| 麻豆精品在线视频| 六月婷婷一区| 亚洲精品激情| 在线亚洲人成| 久久久久免费av| 亚洲a成人v| 国产精品亚洲欧美| 九九综合在线| 在线一区视频| 国产aa精品| 亚洲三区欧美一区国产二区| 成人日韩在线| 欧美午夜三级| 欧美日韩视频| 国产福利亚洲| 精品日韩一区| 亚洲精品成人一区| 国产欧美在线观看免费| 女人天堂亚洲aⅴ在线观看| 亚洲专区一区| 日本不良网站在线观看| 婷婷国产精品| 国产成人精品一区二区三区视频 | 欧美视频一区| 免费在线欧美黄色| 综合干狼人综合首页| 69堂免费精品视频在线播放| 91精品精品| 日韩一区二区三区四区五区| 三上悠亚国产精品一区二区三区| 国产高清一区| 韩国女主播一区二区三区| 国产精品欧美三级在线观看| 精品国产不卡一区二区| 中文字幕一区二区三区四区久久| 国产日韩亚洲| 综合干狼人综合首页| 久久99久久人婷婷精品综合| av高清一区| 四虎国产精品免费久久| 久久美女性网| 亚洲3区在线| 亚洲精品小说| 日韩精品高清不卡| 蜜臀va亚洲va欧美va天堂| 国产欧美欧美| 日韩精品欧美大片| 国产亚洲精品精品国产亚洲综合| 久久亚洲黄色| 国产日韩免费| 激情五月综合| 久久人人99| 欧美日韩1区| 国产美女精品| 国内在线观看一区二区三区| 日韩av一区二区在线影视| 亚洲精品国产嫩草在线观看 | 国产suv精品一区| 亚洲免费黄色| 久久国产电影| 国产日韩欧美中文在线| 视频精品一区| 亚洲精品一区三区三区在线观看| 99精品国产一区二区三区| 美女视频网站久久|