Причин: retrofit.RetrofitError: метод POST должен иметь тело запроса
Я использую retrofit для создания сообщения api, я получаю следующую ошибку при попытке попасть в конечную точку.
Caused by: rx.exceptions.OnErrorNotImplementedException: method POST must have a request body.
at rx.Observable$30.onError(Observable.java:7334)
at rx.observers.SafeSubscriber._onError(SafeSubscriber.java:154)
at rx.observers.SafeSubscriber.onError(SafeSubscriber.java:111)
at rx.internal.operators.OperatorObserveOn$ObserveOnSubscriber.pollQueue(OperatorObserveOn.java:197)
at rx.internal.operators.OperatorObserveOn$ObserveOnSubscriber$2.call(OperatorObserveOn.java:173)
at rx.internal.schedulers.ScheduledAction.run(ScheduledAction.java:55)
at android.os.Handler.handleCallback(Handler.java:739)
at android.os.Handler.dispatchMessage(Handler.java:95)
at android.os.Looper.loop(Looper.java:135)
at android.app.ActivityThread.main(ActivityThread.java:5221)
at java.lang.reflect.Method.invoke(Native Method)
at java.lang.reflect.Method.invoke(Method.java:372)
at
Caused by: java.lang.IllegalArgumentException: method POST must have a request body.
at com.squareup.okhttp.Request$Builder.method(Request.java:236)
at retrofit.client.OkClient.createRequest(OkClient.java:59)
at retrofit.client.OkClient.execute(OkClient.java:53)
at retrofit.RestAdapter$RestHandler.invokeRequest(RestAdapter.java:326)
пытается получить доступ к сообщению api
@POST("/service/v2/auth/ip-address")
rx.Observable<AuthState> verifyIP();
фактический вызов api
LoginService service = CKRestClient.get().create(LoginService.class);
service.verifyIP().observeOn(AndroidSchedulers.mainThread()).subscribe(
new Action1<AuthState>() {
@Override
public void call(AuthState authState) {
}
});
});
Ответы
Ответ 1
Похоже, что Retrofit хочет, чтобы POST-запросы имели полезную нагрузку. Там уже проблема: https://github.com/square/retrofit/issues/854
В качестве обходного пути вы можете сделать что-то вроде этого:
@POST("/service/v2/auth/ip-address")
rx.Observable<AuthState> verifyIP(@Body Object dummy);
а затем выполните:
LoginService service = CKRestClient.get().create(LoginService.class);
service.verifyIP(null).observeOn(AndroidSchedulers.mainThread()).subscribe(
new Action1<AuthState>() {
@Override
public void call(AuthState authState) {
// ...
}
});
});
Или, если service.verifyIP(null)
выбрасывает NPE, замените его на service.verifyIP("")
или аналогичный.
Ответ 2
Я решил эту проблему, заменив @Query на @Field, вот как:
Не работает код:
@POST("/my/url/path")
Result postToServer(
@Query("user_name") String userName);
Рабочий пример:
@FormUrlEncoded
@POST("/my/url/path")
Result postToServer(
@Field("user_name") String userName);
Для методов, у которых нет полей, мне нужно было добавить пустую строку, как показано ниже
Result postToServer(@Path("my_path") String myPath,
@Body String emptyString);
И назовите его "":
restClient.postToServer(myPath, "");
Ответ 3
Кажется, что Retrofit rel.1.9 подвержен проблеме (https://github.com/square/retrofit/issues/854).
Тем временем подумайте о понижении до rel.1.6 до тех пор, пока не будет исправлена текущая версия.
Проверено, что rel.1.6 не содержит этой конкретной ошибки.
Ответ 4
понизить рейтинг OkHttp до версии 2.3.0
Ответ 5
просто включите в метод @Post
@Body String dummyValue, если тело не требуется, вы должны написать этот запрос и отправить "" на сервер
Ответ 6
@Body String emptyBody
не работал у меня как серверный сервер, с которым я работал, возвращал Bad request
и не принимал пустую строку как тело.
Я только что отправил пустой JSON вместо пустой строки
@POST("/some/url)
Observable<Thing> doThing(@Body JsonElement empty);
а затем я просто вызвал свой метод следующим образом:
doThing(new JsonObject());
Надеюсь, что это поможет, если у кого-то есть аналогичная проблема.