android - 改造 2.0 + RxJava + 错误 JSON 正文

标签 android json retrofit rx-java

我对 RxJava 和 Retrofit 还很陌生,我正在尝试用它来编写我的 API 调用。所有 API 调用都会在错误时返回 JSON 正文,其一般格式为,

{"errors":[{"code":100, "message":"Login/Password not valid", "arguments":null}]}

目前我的登录 API 调用代码(其他也类似)是,

mConnect.login(id, password)
        .subscribe(new Subscriber<Token>() {
            @Override
            public void onCompleted() {
                Log.d(TAG, "onCompleted()");
            }

            @Override
            public void onError(Throwable e) {
                Log.e(TAG, "onError(): " + e);
                if (e instanceof HttpException) {
                  // dump e.response().errorBody()
                }
            }

            @Override
            public void onNext(Token token) {
                Log.d(TAG, "onNext(): " + token);
            }
        });

当我在 onError() 收到错误时,我想自动将错误正文中的 JSON 解码为 POJO 并使用它。有没有办法最好在一个地方为所有其他 API 调用执行此操作。任何帮助表示赞赏。

最佳答案

我建议使用可重复使用的 Transformer连同 onErrorResumeNext运算符来封装您的逻辑。它看起来像这样:

<T> Observable.Transformer<T, T> parseHttpErrors() {
    return new Observable.Transformer<T, T>() {
        @Override
        public Observable<T> call(Observable<T> observable) {
            return observable.onErrorResumeNext(new Func1<Throwable, Observable<? extends T>>() {
                @Override
                public Observable<? extends T> call(Throwable throwable) {
                    if (throwable instanceof HttpException) {
                        HttpErrorPojo errorPojo = // deserialize throwable.response().errorBody();

                        // Here you have two options, one is report this pojo back as error (onError() will be called),
                        return Observable.error(errorPojo); // in this case HttpErrorPojo would need to inherit from Throwable

                        // or report this pojo back as part of onNext()
                        return Observable.just(errorPojo); //in this case HttpErrorPojo would need to inherit from <T>
                    }
                    // if not the kind we're interested in, then just report the same error to onError()
                    return Observable.error(throwable);
                }
            });
        }
    };
}

请注意代码中的注释,因为您必须决定是报告解析后的响应 onError() 还是 onNext()。

然后您可以在 API 调用中的任何位置使用此转换器,如下所示:

mConnect.login(id, password)
        .compose(this.<Token>parseHttpErrors()) // <-- HERE
        .subscribe(new Subscriber<Token>() {
            @Override
            public void onCompleted() {
                Log.d(TAG, "onCompleted()");
            }

            @Override
            public void onError(Throwable e) {
                Log.e(TAG, "onError(): " + e);
                if (e instanceof HttpErrorPojo) {
                  // this will be called if errorPojo was reported via Observable.error()
                }
            }

            @Override
            public void onNext(Token token) {
                Log.d(TAG, "onNext(): " + token);
                if (token instanceof HttpErrorPojo) {
                  // this will be called if errorPojo was reported via Observable.just()
                }
            }
        });

关于android - 改造 2.0 + RxJava + 错误 JSON 正文,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/33977686/

相关文章:

Android、scala 和 eclipse = 不稳定的混合

java - 改造:将嵌套的 JSON 元素解析为列表

java - firebase 实时数据库 W/ClassMapper : No setter/field for found on class

android - 将值传递给另一个 Activity

android - 使用 Dagger2 注入(inject)的 Espresso 测试

javascript - 从 JSON 中获取元素属性名称

javascript - Mobx可观察深度对象

JavaScript 由于 JSON 字符串中的 HTML 实体而崩溃

java - 忽略 RuntimeTypeAdapterFactory 中未注册的子类型

android - 使用Android Clean Architecture处理来自API的错误和成功响应