问题
I use Rxjava and Retrofit to handle the response from a http server.
Most of the time, data response is in this format:
{
code: 'OK',
data: {.....}
}
and sometimes, the data property doesn't exist.
{
code: 'OK'
}
I make a 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;
}
}
and make a Map function to parse it.
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());
}
};
}
When data property doesn't exist, I try to return null, but this is not allowed in Rxjava2.
In the customize Observer, I handle all success scenario in onNext(), so I need to emit a error when data == null.
but I can not return a null, and also cannot return a T by return new T(), so how should I do? Anyone can help me out?
回答1:
Several suggested options:
- As Gson parser will put null in fields with no data, so you can return the entire
BaseResponseobject and check the nullity of data property object at the Subscriber/Observer. You can simply wrap your T value with some
Optionalalike interface, which can have a value, or can have nothing (Java8Optionalprobably not available with android, but you can come up with simple structure likeOptionalyourself), then on youronNext()you can check whether you have a value or not.RxJava2 has new
Observabletype called Maybe, which either emit a single item -onSuccessnotification, or nothing -onComplete()notification, (and also errors):onSubscribe (onSuccess | onCompleted | onError)?You can use
flatMapMaybewith bothObservableorSingle(from the Retrofit service interface), to map some response value to aMaybe, in theflatMapMaybeyou can useMaybe.fromCallableto return null like you did here,Maybe.fromCallablewill treat returned null as no items emitted, and you'll getonComplete(), so you can distinguish between result case (onNext) to the no items case (onComplete).
来源:https://stackoverflow.com/questions/43702427/rxjava-and-retrofit-to-handle-empty-data-response