使用RxJava的retryWhen操作符实现token过期自动刷新
来源:互联网 发布:条数计算java 编辑:程序博客网 时间:2024/05/19 10:10
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>>() { @Override public 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>>() { @Override public 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<?>>() { @Override public ObservableSource<?> apply(@NonNull Observable<Throwable> throwableObservable) throws Exception { return throwableObservable.flatMap(new Function<Throwable, ObservableSource<?>>() { @Override public ObservableSource<?> apply(@NonNull Throwable throwable) throws Exception { if (throwable instanceof TokenExpiredException) { // 如果上面检测到token过期就会进入到这里 // 然后下面的方法就是更新token return 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>() { @Override public void onSubscribe(@NonNull Disposable d) { } @Override public void onNext(@NonNull MobileResponse response) { } @Override public void onError(@NonNull Throwable e) { } @Override public void onComplete() { } }; UpdateMobileRequest request = new UpdateMobileRequest(); 设置参数... updateMobile(observer, request);
TokenExpiredException
public class TokenExpiredException extends Exception { // 什么都不用做,当然上面使用TokenExpiredException的地方也可以用其它不会与网络请求产生的异常冲突的异常}
4.总结
如果数据封装形式不同的话一些地方就需要改动,这里也没有加重试次数的限制。在使用retryWhen的时候我也是找了一大堆文章,虽然没有完全吻合的但是最后摸索摸索也就做了出来。上面的代码在我的项目中是进行过封装的,这里为了演示所以把封装的东西全部省去了。
学习无止境,自己的语言表达和组织能力还是很弱,必须要加把劲了。
- 使用RxJava的retryWhen操作符实现token过期自动刷新
- RxJava+Retrofit实现全局过期token自动刷新的实践
- Rxjava+Retrofit 实现全局过期 Token 自动刷新
- RxJava(六) retryWhen操作符实现错误重试机制
- RxJava retryWhen操作符实现错误重试机制
- RxJava retryWhen操作符实现错误重试机制
- 对RxJava中.repeatWhen()和.retryWhen()操作符的思考
- RxJava操作符repeatWhen()和retryWhen()
- Rxjava操作符(defer,compose,retryWhen)
- RxJava操作符repeatWhen()和retryWhen()
- Retrofit Token过期自动刷新并重新请求接口
- 有关RXjava retryWhen
- 【RxJava】操作符的使用
- 批处理实现自动删除过期文件的定期操作
- RxJava(五) onErrorResumeNext操作符实现app与服务器间token机制
- 使用RxJava实现PullScrollView,PullListView, PullGridView 等进入自动下拉刷新
- Java 华为推送 Access Token过期刷新
- Android RxJava使用介绍(二) RxJava的操作符
- 链表的逆序输出
- 算法分析与设计回溯法之n皇后问题
- 《数学之美》第三章 统计语言模型
- 052day(静态成员)
- 学习计划
- 使用RxJava的retryWhen操作符实现token过期自动刷新
- python入门第一天——控制流
- 复制状态机(State Machine Replication)
- 在Ubuntu 16.04配置VNC Server (灰屏问题解决)
- Monitor项目开发走过的路~子线程Toast全解析
- JavaScript--函数声明、函数表达式、匿名函数、立即执行函数
- 到底怎么做需求分析,技术调研,技术设计?
- C++ 数据结构-树状数组
- 互联网技术体验