介绍
这期内容当中小编将会给大家带来有关使用SpringBoot实现API接口,文章内容丰富且以专业的角度为大家分析和叙述,阅读完这篇文章希望大家可以有所收获。
产品迭代过程中,同一个接口可能同时存在多个版本,不同版本的接口URL,参数相同,可能就是内部逻辑不同,尤其是在同一接口需要同时支持旧版本和新版本的情况下,比如应用发布新版本了,有的用户可能不选择升级,这是后接口的版本管理就十分必要了,根据应用的版本就可以提供不同版本的接口。
本文的代码实现基于SpringBoot 2.3.4-release
<强> 1。定义注解强>
ApiVersion
@Target({应用。类型,ElementType.METHOD}) @Retention (RetentionPolicy.RUNTIME) @Documented 公共@ interface ApiVersion {/* * *版本.x.y.z格式 * * @return */字符串值()默认“1.0.0"; }
价值值默认为1.0.0
EnableApiVersion
/* * *是否开启API版本控制 */@Target (ElementType.TYPE) @Documented @Retention (RetentionPolicy.RUNTIME) @ import (ApiAutoConfiguration.class) 公共@ interface EnableApiVersion { }
在启动类上添加这个注解后就可以开启接口的多版本支持。使用进口引入配置ApiAutoConfiguration。
<强> 2。将版本号抽象为ApiItem类强>
ApiItem
@ data 公共类ApiItem实现Comparable{ 私人int高=1; 私人int中期=0; 私人int低=0; 公共静态最终ApiItem API_ITEM_DEFAULT=ApiConverter.convert (ApiVersionConstant.DEFAULT_VERSION); 公共ApiItem () { } @Override 公共int compareTo (ApiItem右){ 如果(this.getHigh()在right.getHigh ()) { 返回1; }else if (this.getHigh () & lt;right.getHigh ()) { 返回1; } 如果(this.getMid()在right.getMid ()) { 返回1; }else if (this.getMid () & lt;right.getMid ()) { 返回1; } 如果(this.getLow()在right.getLow ()) { 返回1; }else if (this.getLow () & lt;right.getLow ()) { 返回1; } 返回0; } }
为了比较版本号的大小,实现可比接口并重写compareTo(),从高位到低位依次比较。
ApiConverter
公共类ApiConverter { 公共静态ApiItem转换字符串(api) { ApiItem ApiItem=new ApiItem (); 如果(StringUtils.isBlank (api)) { 返回apiItem; } String []=stringutil的细胞。分割(api,“!”); apiItem.setHigh (Integer.parseInt(细胞[0])); 如果细胞。长度比;1){ apiItem.setMid (Integer.parseInt(细胞[1])); } 如果细胞。长度比;2){ apiItem.setLow (Integer.parseInt(细胞[2])); } 返回apiItem; } }
ApiConverter提供静态方法将字符创转为ApiItem。
常量类,定义请求头及默认版本号
公共类ApiVersionConstant {/* * *头指定版本号请求头 */公共静态最终字符串API_VERSION=皒-api-version";/* * *默认版本号 */公共静态最终字符串DEFAULT_VERSION=?.0.0"; }
<强> 3。核心ApiCondition 强>
新建ApiCondition类,实现RequestCondition,重写结合,getMatchingCondition, compareTo方法。
RequestCondition
公共接口RequestCondition{/* * *方法和类上都存在相同的条件时的处理方法 */T (T)相结合;/* * *判断是否符合当前请求,返回零表示不符合 */@Nullable T getMatchingCondition (HttpServletRequest请求);/* * *如果存在多个符合条件的接口,则会根据这个来排的序,然后用集合的第一个元素来处理 */int compareTo (T, HttpServletRequest请求);
以上对RequestCondition简要说明,后续详细源码分析各个方法的作用。
ApiCondition
@Slf4j 公共类ApiCondition实现RequestCondition{ 公共静态ApiCondition空=new ApiCondition (ApiConverter.convert (ApiVersionConstant.DEFAULT_VERSION)); 私人ApiItem版本; 私人布尔空; 公共ApiCondition (ApiItem项){ 这一点。版本=项目; } 公共ApiCondition (ApiItem项,布尔NULL) { 这一点。版本=项目; 这一点。NULL=零; }/* * * & lt; pre> *春天先扫描方法再扫描类,然后调用{@link #结合} *按照方法上的注解优先级大于类上注解的原则处理,但是要注意如果方法上不定义注解的情况。 *如果方法或者类上不定义注解,我们会给一个默认的值{@code空},{@link ApiHandlerMapping} * & lt;/pre> * @param其他方法扫描封装结果 * @return */@Override 公共ApiCondition结合(ApiCondition其他){//选择版本最大的接口 如果(other.NULL) { 返回; } 返回; } @Override 公共ApiCondition getMatchingCondition (HttpServletRequest请求){ 如果(CorsUtils.isPreFlightRequest(请求)){ 返回空; } 字符串version=request.getHeader (ApiVersionConstant.API_VERSION);//获取所有小于等于版本的接口,如果前端不指定版本号,则默认请求1.0.0版本的接口 如果(StringUtils.isBlank(版本)){ log.warn(“未指定版本,使用默认1.0.0版本!”); 版本=ApiVersionConstant.DEFAULT_VERSION; } ApiItem项=ApiConverter.convert(版本); 如果(item.compareTo (ApiItem.API_ITEM_DEFAULT) & lt;0){ 把新的IllegalArgumentException (String.format (“API版本(% s)错误,最低版本(% s)“,版本,ApiVersionConstant.DEFAULT_VERSION)); } 如果(item.compareTo (this.version)在=0){ 返回; } 返回null; } @Override 公共int compareTo (ApiCondition其他HttpServletRequest请求){//获取到多个符合条件的接口后,会按照这个排序,然后得到(0)获取最大版本对应的接口。自定义条件会最后比较 int比较=other.version.compareTo (this.version); 如果(比较==0){ log.warn (“RequestMappingInfo相同,请检查!版本:{}“,other.version); } 返回比较; } } 使用SpringBoot实现API接口