Я хотел бы сделать исключение для подписчиков, если код - это что-то иное, чем 0. Как это возможно с помощью Retrofit и Rx?
Вы можете использовать Observable.flatMap
оператор:
api.request().flatMap(response -> {
if (response.getCode() != 0) {
return Observable.error(new Exception("Remote error occurred"));
}
return Observable.just(response);
});
Я очень предпочел бы писать эту логику только один раз и он применяется ко всем наблюдаемым возвращаемые дооснащения.
К сожалению, для этого нет возможности с помощью retrofit
и rx-java
. Вам есть, чтобы написать код для каждого звонка retrofit
. Единственное, что вы можете сделать, это использовать метод Observable.compose
и уменьшить количество шаблонов, которые вы на самом деле должны писать.
api.request().compose(new ResponseTransformer<Response>());
А вот ResponseTransformer
класс:
public static class ResponseTransformer<T extends Response> implements Observable.Transformer<T, T> {
@Override
public Observable<T> call(final Observable<T> observable) {
return observable.flatMap(response -> {
if (response.getCode() != 0) {
return Observable.error(new Exception("Remote error occurred"));
}
return Observable.just(response);
});
}
}
UPDATE
Ну, как я уже говорил, нет никакого способа избежать шаблонный код, используя только retrofit
и rxjava
, но вы может обойти это с помощью dynamic proxies (обратите внимание, что вам больше не нужно звонить compose
):
final Api api = restAdapter.create(Api.class);
final ClassLoader loader = api.getClass().getClassLoader();
final Class<?>[] interfaces = api.getClass().getInterfaces();
final Api proxy = (Api) Proxy.newProxyInstance(loader, interfaces, new ResponseInvocationHandler(api));
proxy.request().subscribe(response -> {
System.out.println("Success!");
});
ResponseInvocationHandler
класс:
public static class ResponseInvocationHandler implements InvocationHandler {
private final Object target;
public ResponseInvocationHandler(final Object target) {
this.target = target;
}
@Override
@SuppressWarnings({"unchecked"})
public Object invoke(final Object proxy, final Method method, final Object[] args) throws Throwable {
final Object result = method.invoke(target, args);
if (result instanceof Observable) {
return Observable.class.cast(result).compose(new ResponseTransformer<>());
}
return result;
}
}
Спасибо, очень полезно – Nima
@Nima проверить мой обновленный ответ, он мог быть еще более полезным. –