我使用Rxjava和Retrofit来处理来自http服务器的响应。
大多数情况下,数据响应采用以下格式:
{
code: 'OK',
data: {.....}
}
有时,data
属性不存在。
{
code: 'OK'
}
我创建了一个BaseResponse类。
public class BaseResponse<T> implements Serializable {
private String code;
private String msg;
private T data;
public String getCode() {
return code;
}
public String getMsg() {
return msg;
}
public T getData() {
return data;
}
}
并创建一个Map
函数来解析它。
public static <T> Function<BaseResponse<T>, T> applyUnwrapResponse () {
return new Function<BaseResponse<T>, T>() {
@Override
public T apply(@NonNull BaseResponse<T> baseResponse) throws Exception {
if (baseResponse.getCode().equals(Constants.SUCCESS_CODE)) {
// http returned from server
T data = baseResponse.getData();
if (data == null) {
return null; // throw exception: The mapper function returned a null value
return return new T(); // syntax error
// how ?
}
return data;
} else if (baseResponse.getCode().equals(Constants.USER_NOT_LOGGED_IN)) {
// auth token error
throw new UserNotLoginException(baseResponse.getMsg());
}
// unknown error
throw new UnknownServerException(baseResponse.getMsg());
}
};
}
如果data
属性不存在,我会尝试返回null
,但Rxjava2中不允许这样做。
在自定义Observer中,我处理onNext()中的所有success
场景,因此我需要在data == null
时发出错误。
但我无法返回null,也无法通过T
返回return new T()
,所以该怎么办?有人可以帮帮我吗?
答案 0 :(得分:2)
几个建议的选项:
BaseResponse
对象并检查订阅者/观察者处的数据属性对象的无效。你可以简单地用一些Optional
相似的界面包装你的T值,它可以有一个值,或者什么都没有(Java8 Optional
可能不适用于android,但你可以来使用Optional
自己的简单结构,然后在onNext()
上,您可以检查是否有值。
RxJava2有一个名为Maybe的新Observable
类型,它会发出单个项目 - onSuccess
通知,或者没有 - onComplete()
通知,(以及错误) ):
onSubscribe (onSuccess | onCompleted | onError)?
您可以flatMapMaybe
同时使用Observable
或Single
(来自Retrofit服务界面),将一些响应值映射到Maybe
{{1}您可以使用flatMapMaybe
返回null,就像您在此处所做的那样,Maybe.fromCallable
会将返回的null视为没有项目发出,并且您将获得Maybe.fromCallable
,因此您可以区分结果案例(onComplete()
)到无项目案例(onNext
)。