RxJava2 / Retrofit2-обработка null для 204 запросов PUT и DELETE

Итак, я работаю с 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'

2 ответов


нужно объявить свой метод запроса в Retrofit как:

@DELETE(...)
Call<Void> deleteFile(...args);

в RxJava ваш Observable должен быть набран:

@DELETE(...)
Observable<Response<Void>> deleteFile(...args);

на onNext() или doOnNext() вы получаете Response обычно, если запрос успешен.

С Void не будет отправлять тело ответа преобразователю для дальнейшей десериализации. Все пусто-ответ Calls должен быть набран как Void.


поскольку у вас есть RxJava2 и retrofit 2, Вы можете использовать более читаемый способ описания того, что вы действительно хотите от конечной точки с помощью Completable.

Completable возвращает только onComplete() и onError(Exception) таким образом, вы знаете, что происходит в тот момент, когда вы его видите(вас волнует только выполнение, а не возвращаемое значение), и не удивляйтесь, что будет под Response<Void>.

поэтому ваш вызов конечной точки должен выглядеть так:

@DELETE(...)
Completable deleteFile(...args);

больше типов поддерживаются, см. Дооснащение 2 RxJava 2 Адаптер страница.Single это тот, который выделяется с точки зрения вызовов API.