当前位置: 首页 > 知识库问答 >
问题:

RxJava+retrifit->BaseObservable用于集中式响应处理的API调用

闾丘博超
2023-03-14

例如:对于来自服务器的特定错误代码,我在响应正文中接收一个新的Auth令牌,刷新该令牌,然后克隆。当然,服务器的响应还有其他几个全局行为。

当前解决方案(不含Rx):

    public abstract void onResponse(Call<T> call, Response<T> response, boolean isSuccess);

    public abstract void onFailure(Call<T> call, Response<T> response, Throwable t, boolean isTimeout);

    @Override
    public void onResponse(Call<T> call, Response<T> response) {
        if (_isCanceled) return;

        if (response != null && !response.isSuccessful()) {
            if (response.code() == "SomeCode" && retryCount < RETRY_LIMIT) {
                TokenResponseModel newToken = null;
                try {
                    newToken = new Gson().fromJson(new String(response.errorBody().bytes(), "UTF-8"), TokenResponseModel.class);
                } catch (Exception e) {
                    e.printStackTrace();
                }

                    SomeClass.token = newToken.token;
                    retryCount++;
                    call.clone().enqueue(this);
                    return;
                }
            }
        } else {
            onResponse(call, response, true);
            removeFinishedRequest();
            return;
        }

        onFailure(call, response, null, false);
        removeFinishedRequest();
    }

    @Override
    public void onFailure(Call<T> call, Throwable t) {
        if (_isCanceled) return;

        if (t instanceof UnknownHostException)
            if (eventBus != null)
                eventBus.post(new NoConnectionErrorEvent());

        onFailure(call, null, t, false);
        removeFinishedRequest();
    }

我的问题是:在最终链接(或重试)回订阅服务器方法之前,有没有什么方法可以实现这种集中式响应处理行为?

共有1个答案

韦澄邈
2023-03-14

您提供的两个链接是一个非常好的起点,我用来构造解决方案来应对意外

  • 有时由于暂时缺乏网络连接而发生网络错误,或者切换到低穿透网络标准(如EDGE),这会导致SocketTimeoutException
  • 服务器错误->有时由于服务器过载而发生

我已经重写了calladapter.Factory来处理错误并对它们做出适当的反应。

重写calladapter.Factory以处理错误:

public class RxCallAdapterFactoryWithErrorHandling extends CallAdapter.Factory {
    private final RxJavaCallAdapterFactory original;

    public RxCallAdapterFactoryWithErrorHandling() {
        original = RxJavaCallAdapterFactory.create();
    }

    @Override
    public CallAdapter<?> get(Type returnType, Annotation[] annotations, Retrofit retrofit) {
        return new RxCallAdapterWrapper(retrofit, original.get(returnType, annotations, retrofit));
    }

    public class RxCallAdapterWrapper implements CallAdapter<Observable<?>> {
        private final Retrofit retrofit;
        private final CallAdapter<?> wrapped;

        public RxCallAdapterWrapper(Retrofit retrofit, CallAdapter<?> wrapped) {
            this.retrofit = retrofit;
            this.wrapped = wrapped;
        }

        @Override
        public Type responseType() {
            return wrapped.responseType();
        }

        @SuppressWarnings("unchecked")
        @Override
        public <R> Observable<?> adapt(final Call<R> call) {
            return ((Observable) wrapped.adapt(call)).onErrorResumeNext(new Func1<Throwable, Observable>() {
                @Override
                public Observable call(Throwable throwable) {
                    Throwable returnThrowable = throwable;
                    if (throwable instanceof HttpException) {
                        HttpException httpException = (HttpException) throwable;
                        returnThrowable = httpException;
                        int responseCode = httpException.response().code();
                        if (NetworkUtils.isClientError(responseCode)) {
                            returnThrowable = new HttpClientException(throwable);
                        }
                        if (NetworkUtils.isServerError(responseCode)) {
                            returnThrowable = new HttpServerException(throwable);
                        }
                    }

                    if (throwable instanceof UnknownHostException) {
                        returnThrowable = throwable;
                    }

                    return Observable.error(returnThrowable);
                }
            }).retryWhen(new RetryWithDelayIf(3, DateUtils.SECOND_IN_MILLIS, new Func1<Throwable, Boolean>() {
                @Override
                public Boolean call(Throwable throwable) {
                    return throwable instanceof HttpServerException
                            || throwable instanceof SocketTimeoutException
                            || throwable instanceof UnknownHostException;
                }
            }));
        }
    }
}

HttpServerException只是一个自定义异常。

retrofit.builder中使用它

Retrofit retrofit = new Retrofit.Builder()
        .addCallAdapterFactory(new RxCallAdapterFactoryWithErrorHandling())
        .build();
 类似资料:
  • 我目前正试图把精力放在RxJava上,但我在以优雅的方式处理服务调用异常方面遇到了一点麻烦。 基本上,我有一个(改型)服务,它返回一个。的定义如下: 现在,我想要的是将该泛型响应映射到data JsonElement字段中包含的(我假设您不关心对象的外观,所以我不会用它污染文章)。下面的代码对于success案例非常有效,但是我找不到一个很好的方法来处理我的API异常: 有没有更好的办法做到这一点

  • 我用改型/rxJava调用我的API,得到了一个可观察的响应,就像一个BreedDog列表 ...你可以看到我的代码: 这是可行的,但是现在,对于列表中的每一项,我都需要调用API来获取URL图像并更新列表。。但我不知道怎么。。。我试着在Observable中更改我的单个响应,并使用了flatMap或flatMapIterate之类的运算符。。等等,但每次我都会在对象上出错。。没有一个例子。。。等

  • 问题内容: 我正在将现有的应用程序移植到Flux,并且对一个主题有些困惑。假设我有几个API端点,它们返回两级或三级嵌套对象。 例如,可能返回架构的JSON响应 如您所见,有各种各样的用户处于不同的嵌套级别: 如果我想在获取文章时随时使用新数据进行更新,则必须编写一个怪异的方法来检查文章API响应上的所有嵌套实体。而且,将存在很多重复,因为还有其他API端点具有不同的架构,有时文章嵌入在用户内部(

  • 我需要检查用户在请求websocket连接时是否提供了有效的令牌。对于验证,调用验证服务器是必要的。我如何同步实现它,以便websocket处理程序不会在有答案之前结束。我正在使用vertx框架。

  • 问题内容: 我的网络服务返回一个JSON对象,如下所示 即,当我将此地址放入chrome浏览器中时,我可以到达上面。 我正在尝试在浏览器中阅读此内容,以便可以创建一个下拉选项…但是从以下代码开始我一无所获: 我总是在警报框中。我用fiddler2再次检查了Web服务请求/响应是否正常,我什至可以拦截Web服务和浏览器之间的json对象。 我也试过 我又得到了空。 我已经看过Ajax要求的json响

  • 我有一个向服务器发送数据的调用。如果一切正常,服务器会返回一个无效的响应。但是当有错误时,我会得到数据。 当有错误时,为了管理这个情况,我有一个对象。问题是,当请求成功时,改造会抛出一个异常,消息是: