RXjava和Retrofit处理空数据响应
RXjava and Retrofit to handle empty data response
我使用 Rxjava 和 Retrofit 来处理来自 HTTP 服务器的响应。
大多数时候,数据响应是这种格式:
{
code: 'OK',
data: {.....}
}
有时 data
属性 不存在:
{
code: 'OK'
}
我做了一个BaseResponse
class.
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
属性不存在时,我尝试return null
,但是Rxjava2.[=36中不允许这样做=]
在自定义观察者中,我在 onNext() 中处理所有 success
场景,因此我需要在 data == null
.
时发出错误
但是我不能return null,也不能return a T
by return new T()
,怎么办?谁能帮帮我?
几个建议的选项:
- 由于 Gson 解析器会将空值放入没有数据的字段中,因此您可以 return 整个
BaseResponse
对象并检查数据 属性 对象在 [=46] 处的空值=].
你可以简单地用一些 Optional
类似的接口包装你的 T 值,它可以有一个值,也可以什么都没有(Java8 Optional
可能没有android 可用,但你可以自己想出像 Optional
这样的简单结构),然后在你的 onNext()
上你可以检查你是否有值。
RxJava2 有一个名为 Maybe 的新 Observable
类型,它要么发出单个项目 - onSuccess
通知,要么什么都不发出 - onComplete()
通知, (还有错误):
onSubscribe (onSuccess | onCompleted | onError)?
您可以将 flatMapMaybe
与 Observable
或 Single
(来自 Retrofit 服务接口)一起使用,以将一些响应值映射到 Maybe
,在 flatMapMaybe
你可以像这里一样使用 Maybe.fromCallable
到 return null,Maybe.fromCallable
会将 returned null 视为没有发出任何项目,你会得到 onComplete()
,因此您可以区分结果案例 (onNext
) 和无项目案例 (onComplete
)。
我使用 Rxjava 和 Retrofit 来处理来自 HTTP 服务器的响应。
大多数时候,数据响应是这种格式:
{
code: 'OK',
data: {.....}
}
有时 data
属性 不存在:
{
code: 'OK'
}
我做了一个BaseResponse
class.
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
属性不存在时,我尝试return null
,但是Rxjava2.[=36中不允许这样做=]
在自定义观察者中,我在 onNext() 中处理所有 success
场景,因此我需要在 data == null
.
时发出错误
但是我不能return null,也不能return a T
by return new T()
,怎么办?谁能帮帮我?
几个建议的选项:
- 由于 Gson 解析器会将空值放入没有数据的字段中,因此您可以 return 整个
BaseResponse
对象并检查数据 属性 对象在 [=46] 处的空值=]. 你可以简单地用一些
Optional
类似的接口包装你的 T 值,它可以有一个值,也可以什么都没有(Java8Optional
可能没有android 可用,但你可以自己想出像Optional
这样的简单结构),然后在你的onNext()
上你可以检查你是否有值。RxJava2 有一个名为 Maybe 的新
Observable
类型,它要么发出单个项目 -onSuccess
通知,要么什么都不发出 -onComplete()
通知, (还有错误):onSubscribe (onSuccess | onCompleted | onError)?
您可以将
flatMapMaybe
与Observable
或Single
(来自 Retrofit 服务接口)一起使用,以将一些响应值映射到Maybe
,在flatMapMaybe
你可以像这里一样使用Maybe.fromCallable
到 return null,Maybe.fromCallable
会将 returned null 视为没有发出任何项目,你会得到onComplete()
,因此您可以区分结果案例 (onNext
) 和无项目案例 (onComplete
)。