android - 使用 RxAndroid 根据特定错误消息改进获取授权 token

标签 android rx-java retrofit2 rx-android

我有一堆改进的可观察对象,每个请求的 header 中都需要授权 token 。 token 的有效期为一小时。

@GET("objects/abc")
    Observable<List<Object>> apiCustomView(@Query("isMobileViews") boolean isMobileViews);

这是我的 Retrofit 服务类,其中为每个请求提供授权 token 。

class Factory {
        public static RetrofitService create() {
            Interceptor interceptor = chain -> {
                Request newRequest = chain.request().newBuilder().addHeader("Authorization",
                        "Bearer "+ Util.getSharedPref("token")).build();
                return chain.proceed(newRequest);
            };

            OkHttpClient.Builder builder = new OkHttpClient.Builder();
            builder.interceptors().add(interceptor);
            OkHttpClient client = builder.build();

            Retrofit retrofit = new Retrofit.Builder()
                    .baseUrl("http://url.com/api/")
                    .client(client)
                    .addConverterFactory(GsonConverterFactory.create())
                    .addCallAdapterFactory(RxJavaCallAdapterFactory.create())
                    .build();
            return retrofit.create(RetrofitService.class);
        }
    }

这里使用服务来获取数据 -

retrofitService.apiCustomView(isMobileViews)
   .observeOn(AndroidSchedulers.mainThread())
   .subscribeOn(application.defaultSubscribeScheduler())
   .subscribe(new Subscriber < List < Object >> () {
    @Override
    public void onCompleted() {
     if (!mObjects.isEmpty()) {
      // Add to database and present data
     }
    }

    @Override
    public void onError(Throwable error) {
     // Present Data from Database
    }

    @Override
    public void onNext(List < Object > objectList) {
    mObjects = objectList;
    }
 });

我想修改请求,以便每当收到授权失败错误时,我都会获取授权 token 并恢复相同的请求。对于任何其他类型的错误,我想显示保存的数据。

最佳答案

您可以通过更改 Observable 的返回类型来访问 Retrofit 的网络响应:

@GET("objects/abc")
Observable<Response<List<Object>>> apiCustomView(@Query("isMobileViews") boolean isMobileViews);

然后您可以在平面图中检查错误类型:

retrofitService.apiCustomView(isMobileViews)
   .flatMap(new Func1<Response<List<Object>>, Observable<List<Object>() {
        @Override
        public Observable<List<Object>> call(Response<List<Object>> response) {

            if (response.isSuccess()) {
                return Observable.just(response.body());
            }
            else if (response.code() == 403) {
                // get new auth token and try again
                return getNewAuthKeyAndTryAgain();
            }
            else {
                return Observable.error(/* create an exception*/)
            }
        }
   })
   .subscribeOn(application.defaultSubscribeScheduler())
   .observeOn(AndroidSchedulers.mainThread())
   .subscribe(...);

要获取新的身份验证 token 并再次运行请求,我将创建一个执行此操作的函数:

private Observable<List<Object>> getNewAuthKeyAndTryAgain() {

    return retrofitService
                .getNewKey()
                .flatMap(new Func1<String, Observable<Response<List<Object>>>>() {
                    @Override
                    public Observable<Response<List<Object>>> call(String s) {

                        // save key where you need to
                        return retrofitService.apiCustomView(isMobileViews);
                    }
                })
                .flatMap(new Func1<Response<List<Object>>, Observable<List<Object>>>() {
                    @Override
                    public Observable<List<Object>> call(Response<List<Object> response) {
                        return response.body();
                    }
                });
}

关于android - 使用 RxAndroid 根据特定错误消息改进获取授权 token ,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/37588208/

相关文章:

java - AndroidManifest.xml - 指定的属性 'manifest' 不存在

java - 由 : java. lang.OutOfMemoryError 引起(启动新 Activity )

java - RxJava 的 Single 是否有等效的 Subject?

android - 使用 Retrofit 的 API 响应对于某些不为 null 的参数返回 null

java - Retrofit2 GET 请求在尝试检索 JSON 数组时返回空列表

android - 在 cordova cli 插件构建中在哪里设置类路径

android - 如何将android webview缩放到特定高度

java - Flowable.map() 中长时间运行的操作会阻止所有订阅者

java - 如何合并并行处理 Observables,同时将同一 Observable 中的项目分组在一起

spring-boot - kotlin 中的 spring 应用程序行为怪异