後付けを使用してポスト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) {
}
});
});
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("")
または類似のものに置き換えます。
@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, "");
Retrofit rel.1.9はこの問題( https://github.com/square/retrofit/issues/854 )の影響を受けやすいようです。
それまでの間、現在のリリースが修正されるまでrel.1.6にダウングレードすることを検討してください。 rel.1.6にはこの特定のバグがないことが確認されています。
_@Body String emptyBody
_は、私が使用していたバックエンドサーバーとして機能せず、_Bad request
_を返し、空の文字列を本文として受け入れませんでした。
空の文字列ではなく空のJSONを送信しました
@POST("/some/url) Observable<Thing> doThing(@Body JsonElement empty);
それから私はこのように私のメソッドを呼び出しました:
doThing(new JsonObject());
誰かが同様の問題を抱えている場合に役立つことを願っています。
okHttpをバージョン2.3.0にダウングレード
@Postメソッドに含めるだけ
@Body String dummyValue、本文が不要な場合は、このクエリを記述して ""をサーバーに送信する必要があります