因此,我正在使用明确定义的API,旨在不在DELETE
和PUT
操作上返回有效负载正文。
这在Rx 0.X和Rx 1.x中是可接受的。现在我正在更新到Rx 2并且存在一个存在的危机,我应该如何处理空值。内容长度和正文当然是空的,导致:
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)
在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'
答案 0 :(得分:26)
您需要在Retrofit
中声明您的请求方法,如:
@DELETE(...)
Call<Void> deleteFile(...args);
在RxJava中,您的Observable
必须输入:
@DELETE(...)
Observable<Response<Void>> deleteFile(...args);
在onNext()
或doOnNext()
,如果请求成功,您通常会收到Response
。
让Void
不会将响应主体发送到转换器以进行进一步的反序列化。所有空回复Call
都应输入为Void
。
答案 1 :(得分:12)
由于你有一个RxJava2和改进2,你可以使用一种更易读的方式,使用Completable
从端点描述你真正想要的东西。
Completable
按设计只返回onComplete()
和onError(Exception)
,这样一旦你看到它就知道发生了什么(你只关心执行而不是返回值)并且不要怀疑Response<Void>
下的内容。
因此,您的端点调用应如下所示:
@DELETE(...)
Completable deleteFile(...args);
支持更多类型,请参阅Retrofit 2 RxJava 2 Adapter页面。Single
是一个在api调用方面脱颖而出的类型。
答案 2 :(得分:0)
对于仍在寻找答案的人:将Void替换为一些空类可以解决我的问题。像这样:
class EmptyResponse {}
并仅使用此类代替Void