java后端 解决app接口版本管理问题

当app迭代时需要,java后端的接口也可能会迭代。
相同的接口,传参和处理方式都会不懂,如果在代码中做向下兼容不可行了,就需要写多个接口进行版本区分。当版本接口不多时,可以通过接口传参然后判断来实现,但是版本接口过多时,在接口中做判断就会效率低下。
但是多个接口暴露出去是同一个访问路径。这样对于app端是察觉不到的。
这里采用拦截器和转发模式,进行请求分发。

首先定义统一接口的版本命名,这里采用v加数字的形式

@RestController
@RequestMapping("/test")
public class TestController {

@PostMapping("/test")
public String get(String name){
    return "测试"+name;
}

@PostMapping("/test/v1")
public String pist(String name){
    System.out.println(name);
    return "测试v1------"+name;
}
@PostMapping("/test/v2")
public String aa(@RequestBody Map<String,Object> map){
    System.out.println(map.get("name"));
    return "测试v2-----"+map.get("name");
}
}

然后创建一个类,进行版本的接口注册

/**
* 配置多版本的接口
 * 根据版本号进行接口匹配
 * @author liudong
 */
public class VersionMap {
private HashMap<String,String> urls=new HashMap<>();
private VersionMap(){
    //此处配置接口数据(接口,版本列表 逗号隔开 模式 v1-vn)
    urls.put("/test/test","v1,v2");
}
private static class SingletonInstance {
    private static final VersionMap INSTANCE = new VersionMap();
}

public static VersionMap getInstance() {
    return SingletonInstance.INSTANCE;
}

public HashMap<String, String> getUrls() {
    return urls;
}

public void setUrls(HashMap<String, String> urls) {
    this.urls = urls;
}
}

然后写核心实现 VersionInterceptor拦截器

/**
 * 版本拦截器
 * @author liudong
 */
public class VersionInterceptor implements HandlerInterceptor{
	/**
 * 接口版本拦截器
 * 对指定的接口进行版本连接
 * 根据cookie中javaVersion转发到不同的版本接口中
 * request中的参数以最终对应接口的参数为准
 * 向下兼容模式
 * 最大容错模式
 */
@Override
public boolean preHandle(HttpServletRequest request, HttpServletResponse response,
                         Object handler) throws Exception {
    Cookie[] aa = request.getCookies();
    //后台版本
    String javaVersion="";
    //app版本
    String appVersion="";
    //设备
    String equipment="";
    if (aa==null){
        LoggerTools.addInfoLogger("javaVersion");
    }
    if (("javaVersion").equals(aa[0].getName().trim())){
        javaVersion=aa[0].getValue();
    }else {
        //无版本传入默认最低版本(向下兼容模式)
        return true;
    }
    String url = request.getServletPath().split("\\.")[0];

    VersionMap versionUrl = VersionMap.getInstance();
    String versions = versionUrl.getUrls().get(url);
    //默认最大版本
    if (versions.contains(javaVersion)){
        url = url+"/"+javaVersion+".do";

    }else {
    	//传入当前版本不在注册中,返回最后一个版本
        String[] versionUrls = versions.split(",|,");
        url= url+"/"+versionUrls[versionUrls.length-1];
    }
    //携带参数进行转发
    request.getRequestDispatcher(url).forward(request,response);
    return false;
}

@Override
public void postHandle(HttpServletRequest httpServletRequest,
                       HttpServletResponse httpServletResponse,
                       Object o, ModelAndView modelAndView) throws Exception {

}

@Override
public void afterCompletion(HttpServletRequest httpServletRequest,
                            HttpServletResponse httpServletResponse,
                            Object o, Exception e) throws Exception {

}
}

这里采用cookie进行数据传输,也可以采用其他方式,比如session之类的。
这里的接口后面需要加.do进行情况,所有截取方式请按具体情况进行区分。

我们将最终的接口版本与app端协定,app端在cookie中放置javaVersion。我们获取进行版本管理。

过滤器转发规则:
当没有指定参数传入时,访问初始接口 /test
当有参数传入时,访问指定接口,
当传入参数,不在注册列表时,访问最终版本接口。
所以版本接口的注册书写是按顺序,从左到右,从旧到新的。

接口的版本命名规则。
同一个接口不是按规则的。
接口的版本命名是根据java发布的版本进行命名的。
比如有两个接口 /a 和 /b
/a已经发布了三版 /a/v1 /a/v2
但是/b没有更新过
下一个版本时
/b要更新了
/b 的下一版命名应该是 /b/v3
如果是/b/v1 或者 /b/v2 时
上一版app传入的是v2
/a 接口访问的是/a/v2
/b 接口访问的应该是/b 而不是/b/v1
所以/b接口的下一版命名应该是在最大的版本号的基础上加一 /b/v3

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值