RxJava2/Retrofit2 - 为204 PUT和DELETE请求处理null

isu*_*hes 12 rx-java retrofit2 okhttp3

因此,我正在使用一个明确定义的API,旨在不返回有效负载主体DELETEPUT操作.

这在Rx 0.X和Rx 1.x中是可接受的.现在我正在更新到Rx 2并且存在一个存在的危机,我应该如何处理空值.内容长度和正文当然是null,导致:

java.lang.NullPointerException: Null is not a valid element
   at io.reactivex.internal.queue.SpscLinkedArrayQueue.offer(SpscLinkedArrayQueue.java:68)
   at io.reactivex.internal.operators.observable.ObservableObserveOn$ObserveOnObserver.onNext(ObservableObserveOn.java:116)
   at io.reactivex.internal.operators.observable.ObservableSubscribeOn$SubscribeOnObserver.onNext(ObservableSubscribeOn.java:63)
Run Code Online (Sandbox Code Playgroud)

在doOnNext中.

我见过很多人的建议Optional<>但是我也需要支持Java7以用于用例原因.我尝试了后端移植,但我无法让它工作.我也不想膨胀并为他们的版本导入Guava库.

我也注意到flatMap也可以帮我处理这个与地图相反的问题,而我正在阅读这些差异.

目前我有一个非常粗糙的OkHttp3拦截器,它将检查状态,检查有效负载是否为空,并添加错误的虚拟内容.

我也试过添加转换工厂.

任何人都可以提供建议并指导我正确的道路是什么?当然,API可以改变,但204不应该因为它的定义为HTTP状态代码而具有有效载荷.

相关依赖

compile('com.squareup.retrofit2:retrofit:2.1.0') {
     exclude module: 'okhttp'
} 
compile 'com.squareup.retrofit2:converter-gson:2.1.0'
compile 'com.jakewharton.retrofit:retrofit2-rxjava2-adapter:1.0.0'
compile 'com.squareup.okhttp3:okhttp:3.5.0'
compile 'com.squareup.okhttp3:logging-interceptor:3.5.0'

compile 'io.reactivex.rxjava2:rxjava:2.0.5'
compile 'io.reactivex.rxjava2:rxandroid:2.0.1'
compile 'com.trello.rxlifecycle2:rxlifecycle:2.0.1'
compile 'com.trello.rxlifecycle2:rxlifecycle-components:2.0.1'
Run Code Online (Sandbox Code Playgroud)

Nik*_*ski 28

您需要声明您的请求方法,Retrofit如:

@DELETE(...)
Call<Void> deleteFile(...args);
Run Code Online (Sandbox Code Playgroud)

在RxJava中你Observable必须输入:

@DELETE(...)
Observable<Response<Void>> deleteFile(...args);
Run Code Online (Sandbox Code Playgroud)

onNext()或者doOnNext()您将收到Response正常,如果请求是成功的.

Void不会响应主体发送到转换器进一步反序列化.所有空响应Call应该键入为Void.

  • 这个问题是即使抛出错误,仍然会调用subcribe块.如果出现Void响应错误,则throwable错误块永远不会命中 (4认同)

Mat*_*Bos 12

由于您有一个RxJava2和改进2,您可以使用更可读的方式使用a来描述您真正想要的端点Completable.

Completable通过设计只返回onComplete(),onError(Exception)所以你知道你看到它的那一刻正在发生什么(你只关心执行而不是返回值)并且不知道将会发生什么Response<Void>.

所以你的端点调用应该如下所示:

@DELETE(...)
Completable deleteFile(...args);
Run Code Online (Sandbox Code Playgroud)

支持更多类型,请参阅Retrofit 2 RxJava 2适配器页面.Single是一个在api电话方面脱颖而出的人.

  • 谢谢!这是正确的答案.它没有@MobileMon在接受的答案中找到的缺陷. (3认同)