RxJava和Retrofit - 根据服务器响应提升自定义异常

时间:2015-05-10 17:01:28

标签: android retrofit rx-java

我希望Retrofit根据服务器响应提出自定义异常。例如,在以下结构中:

{
"code":0,
"message":"OK",
"data":{....}
}

如果code不是0,我想为订阅者引发一个例外。如何使用Retrofit和Rx?我更喜欢只编写一次这个逻辑,并将它应用于改造返回的所有可观测量。

3 个答案:

答案 0 :(得分:7)

  

如果代码不是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);
});
  

我更喜欢只编写一次这个逻辑,并将其应用于改造返回的所有可观测量。

不幸的是,使用retrofitrx-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);
        });
    }
}

<强>更新

好吧,正如我所说,没有办法避免仅使用retrofitrxjava的样板代码,但您可以使用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;
    }
}

答案 1 :(得分:1)

我建议采用不同的方法。

您需要使用自定义拦截器实现自定义OkHttp客户端。

Jpanel

在您的拦截器中,根据返回的代码,您可以正常进行或抛出异常。

这样的事情:

        OkHttpClient client = new OkHttpClient();
        client.interceptors().add(new MyInterceptor());
        mAdapter = new RestAdapter.Builder().setEndpoint(Consts.ENDPOINT).setClient(new OkClient(client))
                .setLogLevel(RestAdapter.LogLevel.BASIC).build();

答案 2 :(得分:0)

1个自定义string arr [2][2][2]= { { {"abcd","qwer"}, {"efgh","tyui"} }, { {"ijkl","zxcv"}, {"mnop","bnmo"} } };

cout<<arr [1] [0] [1] [1]<<endl;

2个用户喜欢:

Observable.Operator