1.问题描述

我们的项目中请求与登录相关接口时需要带上sessionId这个参数,当发现token过期的时候就需要走刷新token的接口,获取最新的token,然后再重新进行请求。

如果项目中是用OkHttp网络框架的话,那么可以使用Authenticator或者Interceptor来实现,可以参考这篇文章 http://www.jianshu.com/p/62ab11ddacc8。我刚开始的时候也是使用的Interceptor实现的,拦截请求->检测是否过期->过期则更新token->重新发送请求,但是我发现我的接口回调中的response仍然是token更新之前的!我已经确保了新的请求携带的是最新的token了啊,折腾了好久都没搞定,所以最后就使用了retryWhen来实现。

2.说明

首先要说明我们项目中数据的封装方式

返回的json格式

{"errorCode" : ...   "errorMessage" : .......
}

errorCode和errorMessage是所有请求都会返回的字段,我们就是根据errorCode的值来判断token是否过期,当然你也可能是用状态码或者其它方式,差别只是判断token过期的方法不同而已。

所以我们的封装方式就是有一个MobileResponse基类,包含errorCode和errorMessage两个字段,然后具体的请求继承MobileResponse。

public class MobileResponse {private String errorCode;private String errorMessage;....
}

3.代码实现

Api接口

// 需要使用token的请求
@POST("updateMobile")
Observable<MobileResponse> updateMobile(@Body UpdateMobileRequest updateMobileRequest);// 刷新token的请求
@POST("login")
Observable<LoginResponse> login(@Body LoginRequest request);

调用

public void updateMobile(Observer<MobileResponse> observer, UpdateMobileRequest updateMobileRequest) {Observable.just(null)// 这里调用flatMap方法,主要是需要在这里设置token,这样当更新了token之后再次订阅时,token也是最新的了.flatMap(new Function<Object, Observable<MobileResponse>>() {@Overridepublic Observable<MobileResponse> apply(Object object) throws Exception {// 设置token(我这里token,session意思是一样的)updateMobileRequest.setSessionId(UserInfo.getInstance().getSession());// apiService是我上面Api接口的一个实例return apiService.updateMobile(updateMobileRequest);}}).subscribeOn(Schedulers.io()).unsubscribeOn(Schedulers.io()).observeOn(AndroidSchedulers.mainThread()).flatMap(new Function<MobileResponse, Observable<? extends MobileResponse>>() {@Overridepublic Observable<? extends MobileResponse> apply(@NonNull MobileResponse response) throws Exception {// 判断token是否过期if (ErrorCode.ERROR_NOAUTH.equals(response.getErrorCode())) {return Observable.error(new TokenExpiredException());}return Observable.just(response);}}).retryWhen(new Function<Observable<Throwable>, ObservableSource<?>>() {@Overridepublic ObservableSource<?> apply(@NonNull Observable<Throwable> throwableObservable) throws Exception {return throwableObservable.flatMap(new Function<Throwable, ObservableSource<?>>() {@Overridepublic ObservableSource<?> apply(@NonNull Throwable throwable) throws Exception {if (throwable instanceof TokenExpiredException) {// 如果上面检测到token过期就会进入到这里// 然后下面的方法就是更新tokenreturn apiService.login(HttpMethods.this.buildLoginRequest()).subscribeOn(Schedulers.io()).observeOn(AndroidSchedulers.mainThread()).unsubscribeOn(Schedulers.io()).doOnNext(loginResponse -> {// 保存最新的token// 这里更新完成后就会进行重订阅,从Observable.just(null)重新开始走。UserInfo.getInstance().setSession(AndroidApplication.getInstance(), loginResponse.getSessionId());});} // 如果是其他错误则会调用到observer的onError方法中return Observable.error(throwable);}});}}).subscribe(observer);
}Observer<MobileResponse> observer = new Observer<MobileResponse>() {@Overridepublic void onSubscribe(@NonNull Disposable d) {}@Overridepublic void onNext(@NonNull MobileResponse response) {}@Overridepublic void onError(@NonNull Throwable e) {}@Overridepublic void onComplete() {}};UpdateMobileRequest request = new UpdateMobileRequest();设置参数...updateMobile(observer, request);

TokenExpiredException

public class TokenExpiredException extends Exception {// 什么都不用做,当然上面使用TokenExpiredException的地方也可以用其它不会与网络请求产生的异常冲突的异常
}

4.总结

如果数据封装形式不同的话一些地方就需要改动,这里也没有加重试次数的限制。在使用retryWhen的时候我也是找了一大堆文章,虽然没有完全吻合的但是最后摸索摸索也就做了出来。上面的代码在我的项目中是进行过封装的,这里为了演示所以把封装的东西全部省去了。

学习无止境,自己的语言表达和组织能力还是很弱,必须要加把劲了。

使用RxJava的retryWhen操作符实现token过期自动刷新相关推荐

  1. java app token 失效_请求时token过期自动刷新token操作

    1.在开发过程中,我们都会接触到token,token的作用是什么呢?主要的作用就是为了安全,用户登陆时,服务器会随机生成一个有时效性的token,用户的每一次请求都需要携带上token,证明其请求的 ...

  2. java 后台自动刷新请求_请求时token过期自动刷新token

    1.在开发过程中,我们都会接触到token,token的作用是什么呢?主要的作用就是为了安全,用户登陆时,服务器会随机生成一个有时效性的token,用户的每一次请求都需要携带上token,证明其请求的 ...

  3. python token过期_请求时token过期自动刷新token

    1.在开发过程中,我们都会接触到token,token的作用是什么呢?主要的作用就是为了安全,用户登陆时,服务器会随机生成一个有时效性的token,用户的每一次请求都需要携带上token,证明其请求的 ...

  4. php token 自动过期,请求时token过期自动刷新token

    1.在开发时这例随时幻近我些如机兼灯近我些如机兼灯过程中,我们都会接触到token,token的作用是什么呢?主要的作用就是为了安全,用户登陆时,服务器会随机生成一个有时效性的token,用户的每一次 ...

  5. Vue 消除Token过期时刷新页面的重复提示

    1.问题现象   页面长时间未操作,再刷新页面时,第一次弹出"token失效,请重新登录!"提示,然后跳转到登录页面,接下来又弹出了n个"Token已过期"的后 ...

  6. token过期后刷新token并重新发起请求

    系统登录成功后,后端返回token和refreshToken,所有请求都携带token,token如果过期接口将返回401,此时前端需要拿着refreshToken去刷新token,刷新后将拿到新的t ...

  7. JWT登录过期自动刷新方案与token泄漏解决方案

    概念 简单来说JWT就是通过一定规范来生成token,再用解密算法解密token,就可以获取用户信息了. 优缺点 优点:避免重复查库,存储在客户端,不占用服务端资源 缺点:token是经过base64 ...

  8. token失效自动刷新

    前言 在开发过程中,我们都会接触到token(令牌),为什么要用token呢?主要的作用就是为了安全,用户登录时,服务器会返回一个有时效性的token,用户的每一次请求都需要携带上token,服务器会 ...

  9. token 过期刷新令牌_OkHttp实现全局过期token自动刷新

    问题 一次面试遇到的一个问题,其实也是实际开发中很容易遇到的问题,特此记录一下. 当请求某个接口的时候,我们会在请求的header中携带token消息,但是发现token失效,接口请求报错,怎么马上刷 ...

最新文章

  1. PYTHON——数据存储:MySQL数据库
  2. 【笔记】2010-11-25记录
  3. 记录JS event Loop机制及Node v8事件执行机制
  4. ASP站点无法访问怎么办
  5. Dynatrace成功扩展kubernetes全栈可观察性
  6. 在Vs.net中集成 NDoc生成的 Html Help 2帮助文档
  7. spring cloud 学习(5) - config server
  8. MyBatis基础:MyBatis缓存(5)
  9. 万应低代码CTO胡艳平:浅谈低代码在中大型企业数字化转型中的应用
  10. CVX用户指南之求解器
  11. 怎么用PS为一寸证件照更换底色背景色
  12. 流利阅读 2019 1.6 What happened at Theranos is a dazzling story of deception
  13. 【编译原理】实验二 词法分析程序
  14. sticky粘性定位
  15. 干货!STABLE - 一种无监督高鲁棒性图结构学习框架
  16. 【电脑运用及修理】Mozilla Firefox 浏览器
  17. 网易面试——人工智能工程师
  18. XP Professional SP3 英文版序列号
  19. SSM毕设项目场景理论下城镇消费信贷系统l831r(java+VUE+Mybatis+Maven+Mysql)
  20. 热力四射 2017中国软件生态大会搅动春城

热门文章

  1. WIN11自带微软输入法设置问题 自带键盘版本仍为win10问题、显示繁体问题解决
  2. github python100天_GitHub - 1814931012/Python-100-Days: Python - 100天从新手到大师
  3. 网易云计算机专业课程,网易云课堂推出在线中国大学MOOC课程
  4. 新税码不显示或者税码被人隐藏,发票校验不显示
  5. 龙迅LT6911GX
  6. 边旅游边工作是一种什么样的感受
  7. JAVA并发编程:悲观锁与乐观锁
  8. zbrush 制作护腕1 -- 基础模型
  9. VMware Workstation虚拟机备份及磁盘空间回收
  10. MoveIt教程[11]:Visualizing Collisions