V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
vicky517
V2EX  ›  Android

android http 请求接口设计模式问题

  •  
  •   vicky517 · 2015-12-18 11:54:17 +08:00 · 5716 次点击
    这是一个创建于 3058 天前的主题,其中的信息可能已经有所发展或是发生改变。

    当前开发的 App 又一个问题:
    当请求某个接口时,由于 token 已经失效,所以接口回报错。
    但是产品经理希望 app 能够马上刷新 token ,然后重复请求刚才那个接口,这个过程对用户来说是无感的。

    请求 A 接口-》服务器返回 token 过期-》请求 token 刷新接口-》请求 A 接口

    要实现上述需求的话, Http 应该如何封装。(注:目前 app 即成了 okHttp 模块。)

    14 条回复    2015-12-18 17:16:43 +08:00
    sun2920989
        1
    sun2920989  
       2015-12-18 11:58:05 +08:00
    为什么客户端自己不知道 token 过期了 请求之前不验证的?
    rockyou12
        2
    rockyou12  
       2015-12-18 12:29:40 +08:00
    首先 token 失效肯定要返回一个失效的错误码或信息。然后你写一个 BaseCallback 让你的 callback 都去继承,这样在 BaseCallback 中处理就行了。 BaseCallback 中你用广播还是用 eventbus 都可以
    Vindroid
        3
    Vindroid  
       2015-12-18 13:36:27 +08:00
    token 时效客户端应该是知道的吧?做个守护进程,在 token 快过期前重新登录下就好了。
    vicky517
        4
    vicky517  
    OP
       2015-12-18 13:50:22 +08:00
    http 封装的都是通用的方法,适用任何接口请求:
    凡事涉及到某个接口的 token 过期,都能调用 token 刷新,然后重新调用上一个接口。

    @Vindroid 开启一个进程去做这件事总觉得有点太浪费资源,我是想找到一个比较轻的解决方案


    @sun2920989 你根本没懂我的问题


    @rockyou12 你说的方式我不太明白
    sun2920989
        5
    sun2920989  
       2015-12-18 13:57:41 +08:00
    @vicky517 客户端缓存 token 时设置有效期比 token 最长有效期短五分钟左右防止时间差问题,服务端提供刷新 token 接口,每次获取都获取新的并且刷新新 token 有效期.客户端发起请求之前走一个(有缓存用缓存没缓存则去服务器获取并且缓存)这样的方法获取 token 我确实不知道你怎么会有这种问题出现
    twoyuan
        6
    twoyuan  
       2015-12-18 14:32:59 +08:00
    不知道楼主 okhttp 现在是怎么封装的?

    我们项目中使用 RxJava + Retrofit ,每个接口是以 Observable 的形式返回的,这种情况我们可能会 flatMap 判断 A 接口结果 -> 如果失效再 flatMap 到获取 token 接口 -> 获取 token 成功后保存再 flatMap 到 A 接口。

    如果很多接口需要这样做的话,也是比较容易封装的。
    vicky517
        7
    vicky517  
    OP
       2015-12-18 14:43:59 +08:00
    @twoyuan 明白了 感谢
    rockyou12
        8
    rockyou12  
       2015-12-18 14:52:50 +08:00
    okhttp 一般是 call.enqueue(new Callback<T>() {.........})
    这里你写一个类,如:
    public abstract class MyCallback<T> implements Callback<T> {
    @Override
    public void onResponse(Response<T> response){
    //处理 token 失效
    onResponseDelegate(response);
    }

    @Override
    public void onFailure(Throwable t) {
    //或者这里处理 token 失效
    onFailureDelegate(t);
    }

    //代理方法可有可无,看你具体需求
    public abstract void onResponseDelegate(Response<T> response);
    public abstract void onFailureDelegate(Throwable t);
    }

    之后这样用行了 call.enqueue(new MyCallback<T>() {.........})。这样的好处是对所有连接错误不管是网络层的还是业务逻辑都可以做统一处理。处理就可以用 EventBus post 一个事件让对应的组件去处理。
    twocity
        9
    twocity  
       2015-12-18 14:55:32 +08:00
    可以利用 Okhttp 的 interceptor ,写了个 demo https://gist.github.com/twocity/8344055f9441c508a0ed
    不过我没有测试过
    kyze8439690
        10
    kyze8439690  
       2015-12-18 15:19:18 +08:00
    所以我觉得对每一个请求实现序列化和反序列化是很有必要的,像你这种要求就可以在 token 失败的回调里面保存原请求并刷新 token ,成功之后重试请求。而且在一些自动重试的需求上也很好。比如下次打开自动重试之类……
    kyze8439690
        11
    kyze8439690  
       2015-12-18 15:20:13 +08:00
    不过回调的维持是个问题,可能得请求 id +广播实现。
    Comdex
        12
    Comdex  
       2015-12-18 15:43:33 +08:00
    其实一般 token 的时效都较长,如果失效的话不是应该提醒用户重新登录么?每次访问资源时要发个请求验证一下 token 是否失效不是很浪费资源么?
    Vindroid
        13
    Vindroid  
       2015-12-18 16:48:36 +08:00
    @vicky517 android 的话发送一个 delay 的消息就好,并不会占用过多的资源。
    vicky517
        14
    vicky517  
    OP
       2015-12-18 17:16:43 +08:00
    @rockyou12
    @twocity
    @kyze8439690
    @Vindroid

    感谢给位大神
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   我们的愿景   ·   实用小工具   ·   801 人在线   最高记录 6543   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 23ms · UTC 22:20 · PVG 06:20 · LAX 15:20 · JFK 18:20
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.