在实际项目(Retrofit+RxJava框架)中,有时需要先登录,获取token后再去获取用户信息,此时我们使用flatmap操作符比较好。

在RESTResult对象里,包括请求返回的状态:失败还是成功,错误码,User对象等等,我们根据接口先定义一个返回数据Response实体类:

public class Response<T> extends Entity {

    public boolean isSuccess() {
return infoCode == 1;
}
public boolean isTokenExpired() {
return infoCode == -1;
} public int infoCode;
public String message;
public int size;
public T data;
}

逻辑处理:

  • 登录失败,直接触发onError;
  • 登录成功,根据获得的token请求用户信息接口最终调用subscribe的onNext事件;

如下代码所示:

private void login(final String phone , final String password){
APIWrapper.getInstance().login(phone, password)
.flatMap(new Func1<Response<TokenEntity>, Observable<Response<UserInfo>>>() {
@Override
public Observable<Response<UserInfo>> call(Response<TokenEntity> response) {
if (response.isSuccess()) {
TokenEntity tokenEntity = response.data; return APIWrapper.getInstance().getUserInfo(tokenEntity.token);
} else {
return Observable.error(new ApiException(response.message));
}
}
})
.compose(new RxHelper<Response<UserInfo>>(getString(R.string.wait_to_login_tip)).io_main(LoginActivity.this))
.subscribe(new RxSubscriber<Response<UserInfo>>(this,USER_LOGIN) {
@Override
public void _onNext(Response<UserInfo> response) {
if (response.isSuccess()) {
UserInfo userInfo = response.data;
if (null != userInfo) {
AppApplication.getInstance().saveUserInfo(userInfo);
}
finish();
}
} @Override
public void _onError(String msg) {
ToastUtils.show(LoginActivity.this, msg);
}
});
}

根据上面代码,登陆失败后的处理很关键:

if (response.isSuccess()) {
TokenEntity tokenEntity = response.data; return APIWrapper.getInstance().getUserInfo(tokenEntity.token);
} else {
return Observable.error(new ApiException(response.message));

无论何种原因造成的登陆失败,都应跟用户提示。

ApiException代码:

public class ApiException extends RuntimeException {

    public static final int USER_NOT_EXIST = 100;
public static final int WRONG_PASSWORD = 101;
public static final int ERROR = 2001; public ApiException(int resultCode) {
this(getApiExceptionMessage(resultCode));
} public ApiException(String detailMessage) {
super(detailMessage);
} /**
* 由于服务器传递过来的错误信息直接给用户看的话,用户未必能够理解
* 需要根据错误码对错误信息进行一个转换,在显示给用户
* @param code
* @return
*/
private static String getApiExceptionMessage(int code){
String message ;
switch (code) {
case USER_NOT_EXIST:
message = "该用户不存在";
break;
case WRONG_PASSWORD:
message = "密码错误";
break;
default:
message = "未知错误"; }
return message;
} }

通过RxJava的链式操作,结合恰当的操作符,不仅可以把正常的数据源发射给观察者,同时也可以将错误异常数据源发射给观察者,RxJava比想象中的更强大!

更多参考:Retrofit+RxJava 优雅的处理服务器返回异常、错误

 

Retrofit 使用flatmap操作符时处理错误、异常的更多相关文章

  1. 记录一次排查使用HttpWebRequest发送请求的发生“基础连接已关闭:接收时发生错误”异常问题的过程

    描述:某次更新程序,需要给测试员MM测试,之前都是正常的,更新后给MM测试就报异常System.Net.WebException 基础连接已经关闭:接收时发生错误 -------> System ...

  2. java io流 运行错误时,保存异常到文件里面

    java io流 运行错误时,保存异常到文件里面 下面这个实例,运行后,输入数字,为正确,如果输入字符串,则报错,保存错误信息 //运行错误时,保存异常到文件里面 //下面这个实例,运行后,输入数字, ...

  3. 无法将类型为“Excel.ApplicationClass”的 COM 对象强制转换为接口类 型“Excel._Application”。此操作失败的原因是对 IID 为“{000208D5 -0000-0000-C000-000000000046}”的接口的 COM 组件调用 QueryInterface 因以下错误而失败: 加载类型库/DLL 时出错。 (异常来 自 HRESULT:

    无法将类型为“Excel.ApplicationClass”的 COM 对象强制转换为接口类 型“Excel._Application”.此操作失败的原因是对 IID 为“{000208D5 -000 ...

  4. SQL2008、SQL2013 执行Transact-SQL 语句或者批处理时发生了异常。错误5120

    附加数据库的时候遇到问题,问题描述如下: 附加数据库 对于 服务器"服务器名"失败.(Microsoft.SqlServer.Smo) 执行Transact-SQL 语句或者批处理 ...

  5. 格式化程序尝试对消息反序列化时引发异常: 尝试对参数 http://tempuri.org/ 进行反序列化时出错: GetLzdtArticleResult。InnerException 消息是“反序列化对象 属于类型 lzdt.DTO.Dtolzdt[] 时出现错误。读取 XML 数据时,超出最大

    当遇到这个错误的时候郁闷了好长时间报错是字符串长度过大可是修改了MaxStringContentLength”属性的值却不起作用最后才发现还是因为配置文件配置的问题在服务端 格式化程序尝试对消息反序列 ...

  6. 问题解决_WCF_WCF 接收我服务的 HTTP 响应时发生错误

    原文地址:http://www.cnblogs.com/tianma3798/p/5470974.html 错误内容: System.ServiceModel.CommunicationExcepti ...

  7. vs2010 rdlc .net4.0 卸载 Appdomain 时出错。 (异常来自 HRESULT:0x80131015) 解决办法

    网上一看Appdomain出错,绝大部分都是说控件加载错误.经测试在.net 4.0环境下 rdlc报表很容易发生卸载 Appdomain 时出错. (异常来自 HRESULT:0x80131015) ...

  8. 使用DBCP时发生AbstractMethodError异常

    使用DBCP时发生AbstractMethodError异常,错误描述: Exception in thread "main" java.lang.AbstractMethodEr ...

  9. Ubuntu 使用apt-get时提示错误:无法获得锁 /var/lib/dpkg/lock

    推荐博客:http://blog.sina.com.cn/s/blog_5c1450a8010188ju.html Ubuntu 使用apt-get时提示错误:无法获得锁 /var/lib/dpkg/ ...

随机推荐

  1. net user

    net user 编辑 Net User命令是一个DOS命令,必须在Windows nt以上系统的MS-DOS模式下运行,所以首先要进入MS-DOS模式:选择“开始”菜单的“附件”选项的子选项“命令提 ...

  2. 怎么使用瓦特平台下面的“代码工厂”快速生成BS程序代码

    这里说一下怎么使用瓦特平台下面的“代码工厂”快速生成程序代码 使用平台:windows+"visual studio 2010"+"SqlServer2000+" ...

  3. C#入门篇-4:使用运算符

    using System; using System.Text; using System.Collections; using System.Collections.Generic; using S ...

  4. springdata jpa

    (转自:http://www.cnblogs.com/ityouknow/p/5891443.html) 首先了解JPA是什么? JPA(Java Persistence API)是Sun官方提出的J ...

  5. java替换富文本标签等

    (转自:http://www.cnblogs.com/1246447850qqcom/p/5439366.html) package q;import java.util.regex.Matcher; ...

  6. 习题:最短路计数(SPFA最短路计数)

    最短路计数(洛谷1144)题目描述 给出一个N个顶点M条边的无向无权图,顶点编号为1-N.问从顶点1开始,到其他每个点的最短路有几条.输入输出格式输入格式:输入第一行包含2个正整数N,M,为图的顶点数 ...

  7. 树的合并 connect

    树的合并 connect 题目描述 话说moreD经过不懈努力,终于背完了循环整数,也终于完成了他的蛋糕大餐. 但是不幸的是,moreD得到了诅咒,受到诅咒的原因至今无人知晓. moreD在发觉自己得 ...

  8. 【07】 vue 之 Vue-router

    注意: vue-router@2.x 只适用于 Vue 2.x 版本. vue-router@1.x 对应于Vue1.x版本. 的Github地址:vue-router 文档地址 7.2. vue-r ...

  9. SQL中的CASE WHEN使用

    原文发布时间为:2010-06-04 -- 来源于本人的百度文章 [由搬家工具导入] SQL的条件语句,条件判断语句,SQL的 if else语句。2009-07-20SQL_中的CASE WHEN使 ...

  10. ThickBox弹出框的使用方法

    原文发布时间为:2009-08-22 -- 来源于本人的百度文章 [由搬家工具导入] 请访问:http://www.blueidea.com/articleimg/2007/12/5182/tickb ...