关闭

Retrofit + RxJava 业务状态重定向及分离

标签: RetrofitRxJava
2253人阅读 评论(0) 收藏 举报
分类:

问题

本文主要介绍了在 Retrofit + RxJava 环境下更优雅的解决了以下两个问题:

  1. 将接口业务上的失败重定向到 onError(Throwable e) 输出;
  2. 业务成功时分离出 data 数据由 onNext(T t) 输出;

场景

一般来说,一个友好的接口返回 json 应该是这样的:

{
    "code":200,
    "codeMsg":"查询成功!",
    "data":{
        "city":"北京",
        "temperature":"8℃~20℃",
        "weather":"晴转霾"
    }
}

或者这样的:

{
    "code":200,
    "codeMsg":"查询成功!",
    "data":[
        {
            "city":"北京",
            "temperature":"8℃~20℃",
            "weather":"晴转霾"
        },
        {
            "city":"南京",
            "temperature":"12℃~21℃",
            "weather":"晴"
        }
    ]
}

如果约定好,code == 200,表示业务成功。其他表示业务失败,codeMsg 更详细地描述业务状态信息。例如:

{
    "code":"400",
    "codeMsg":"未知的城市"
}

实现

要知道,利用 Retrofit + Gson (或者其他 Converter ) 可以将返回的 Json 的转换为对象的,那么可以定义以下返回通用类 Model :

/**
 * CommonResponse - 通用类
 * 泛型 T 可以为 List<object> , 也可以是 Object , 也可以为空。
 */
public class CommonResponse<T> {
    private int code;
    private String codeMsg;
    private T data;

    public int getCode() {
        return code;
    }

    public String getCodeMsg() {
        return codeMsg;
    }

    public T getData() {
        return data;
    }

    /**
     * 根据 code 码判断业务状态
     * code == 2xx,表示业务成功。其他表示业务失败,codeMsg 进一步描述业务状态。
     */
    public boolean isSuccess() {
        return code / 100 == 2;
    }
}

为了解决上面提出的两个问题,这里可以使用 RxJava 中的 lift() 来自定义操作:

/**
 * 这里为了示例,简化了Retrofit Service、Api 创建的过程。 
 */
JKApi mApi = JKService.createJKService();
mApi.getWeatherForCity("北京").lift(new Observable.Operator<T, CommonResponse<T>>() {
            @Override
            public Subscriber<? super CommonResponse<T>> call(final Subscriber<? super T> subscriber) {
                return new Subscriber<CommonResponse<T>>() {
                    @Override
                    public void onCompleted() {
                        subscriber.onCompleted();
                    }

                    @Override
                    public void onError(Throwable e) {
                        subscriber.onError(e);
                    }

                    @Override
                    public void onNext(CommonResponse<T> tCommonResponse) {

                        if (tCommonResponse.isSuccess())
                            subscriber.onNext(tCommonResponse.getData());
                        else
                            subscriber.onError(new Throwable(tCommonResponse.getCodeMsg()));
                    }
                };
            }
        });

上面的 lift() 操作想要对每一个符合这样标准的接口都通用,并且顺便对线程指定进行封装。可以 implements Observable.Transformer

public class RedirectResponseTransformer<T> implements Observable.Transformer<CommonResponse<T>, T> {
    @Override
    public Observable<T> call(
        Observable<CommonResponse<T>> CommonResponseObservable) {
        return CommonResponseObservable.subscribeOn(Schedulers.io())
                                       .observeOn(AndroidSchedulers.mainThread())
                                       .lift(new Observable.Operator<T, CommonResponse<T>>() {
                @Override
                public Subscriber<?super CommonResponse<T>> call(
                    final Subscriber<?super T> subscriber) {
                    return new Subscriber<CommonResponse<T>>() {
                            @Override
                            public void onCompleted() {
                                subscriber.onCompleted();
                            }

                            @Override
                            public void onError(Throwable e) {
                                subscriber.onError(e);
                            }

                            @Override
                            public void onNext(
                                CommonResponse<T> tCommonResponse) {
                                if (tCommonResponse.isSuccess()) {
                                    subscriber.onNext(tCommonResponse.getData());
                                } else {
                                    subscriber.onError(new Throwable(
                                            tCommonResponse.getCodeMsg()));
                                }
                            }
                        };
                }
            });
    }
}

最后我们使用 Observable.compose(Transformer transformer) 方法将以上的封装加入到 Rx-Chain 中去:

/**
 * 这里为了示例,简化了Retrofit Service、Api 创建的过程。 
 */
JKApi mApi = JKService.createJKService();
mApi.getWeatherForCity("北京")
    .compose(new RedirectResponseTransformer<WeatherModel>())
    .subscribe(new Subscriber<WeatherModel>() {
                    @Override
                    public void onCompleted() {

                    }

                    @Override
                    public void onError(Throwable e) {
                        showShortToast(e.toString());
                    }

                    @Override
                    public void onNext(WeatherModel weatherModel) {
                        // do something like refresh ui

                    }
                });

到这里,针对上文提出的两个问题已经做了封装。其实利用 RxJava 强大的运算符还可以做很多封装。例如:针对特定异常显示Toast、onComplete() 回调中 dismiss loadingDialog 等。

来自:http://jkyeo.com/2016/03/01/Retrofit-RxJava-业务状态重定向及分离/

0
0
查看评论
发表评论
* 以上用户言论只代表其个人观点,不代表CSDN网站的观点或立场

fiddler重定向本地服务器URL到线上URL

参考:http://docs.telerik.com/fiddler/KnowledgeBase/FiddlerScript/ModifyRequestOrResponse 关键代码 ...
  • u010565244
  • u010565244
  • 2016-04-08 10:39
  • 2426

关于Retrofit2+Okhttp3实现统一添加请求参数和重定向

Android开发中难免会遇到一些比较“不友好”的服务端接口。比如以前遇到的json数据中,某个字段偶尔为Object,偶尔为List… 最近遇到的一个问题就是:所有请求接口都要增加一个token参数...
  • yyh352091626
  • yyh352091626
  • 2016-11-08 15:04
  • 5831

RxJava+Retrofit+MVP 封装带有加载框的Http请求

最近在学习RxJava以及Retrofit,根据所学封装了一个带ProgressBarT弹窗网络请求的demo。并且对过程进行封装,只返回结果。 主要框架:MVP+RxJava
  • jhl122
  • jhl122
  • 2017-03-13 16:28
  • 1128

RxJava与Retrofit实战总结

RxAndroid模块包含RxJava的Android特定的绑定代码。它给RxJava添加了一些类,用于帮助在Android应用中编写响应式(reactive)的组件。它提供了一个可以在给定的And...
  • duanyy1990
  • duanyy1990
  • 2016-08-21 20:49
  • 2879

我们真的需要使用RxJava+Retrofit吗?

可以说RxJava+Retrofit是整个2016年Android 开发圈内最受关注的的组合。各大Android论坛上有大量以RxJava+Retrofit+xxx 为标题的文章,此类文章也备受大家的...
  • TOYOTA11
  • TOYOTA11
  • 2016-12-04 16:35
  • 8057

Retrofit和RxJava结合使用

使用Retrofit的时候就不得不提到RxJava,RxJava是一个基于观察者模式的异步实现。关于RxJava的入门学习,强烈推荐《给Android开发者的RxJava详解》 https://g...
  • tinyzhao
  • tinyzhao
  • 2016-09-30 16:12
  • 1144

使用RxJava优化Retrofit请求

在进行任何一个Google APIs接口调用的时候,很有可能由于access token过期了),会导致我们的请求失败。在这个时候,我们必须重新请求token,然后在请求成功的callback中再次请...
  • codezjx
  • codezjx
  • 2016-04-23 22:28
  • 4474

Android基于Retrofit2.0 +RxJava 封装的超好用的RetrofitClient工具类(六)

csdn :码小白 原文地址: http://blog.csdn.net/sk719887916/article/details/51958010 RetrofitClient基于Ret...
  • sk719887916
  • sk719887916
  • 2016-07-19 17:44
  • 23912

RxJava与Retrofit 结合请求后台数据并解析

1.核心: 一个方法类(HttpMethod)+一个接口(HttpService) public class ADHttpMethods { public static final Strin...
  • meetings
  • meetings
  • 2017-01-06 21:44
  • 17065

RxJava+Retrofit+OkHttp深入浅出-终极封装二(网络请求)

Rxjava+ReTrofit+okHttp背景:    学习Rxjava+Retrofit+okhttp已经一段时间了,发现确实很强大,但是使用起来稍微有点麻烦,在工作中重复的代码太多,所以决定对h...
  • u014610664
  • u014610664
  • 2016-07-18 11:47
  • 173341
    个人资料
    • 访问:10913335次
    • 积分:76597
    • 等级:
    • 排名:第23名
    • 原创:506篇
    • 转载:914篇
    • 译文:4篇
    • 评论:2258条
    打赏
    如果您认为本博客不错,读后觉得有收获,不妨打赏赞助我一下,让我有动力继续写出高质量的博客。



    赠人玫瑰,手有余香。分享技术,传递快乐。

    有心课堂,传递的不仅仅是技术!

    QQ交流群:250468947

    有心课堂会员,请加入VIP QQ交流群:213725333

    github
    我的视频
    博客专栏
    最新评论