web-dev-qa-db-ja.com

原因:retrofit.RetrofitError:メソッドPOSTにはリクエスト本文が必要です

後付けを使用してポスト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) {

                        }
                    });
        });
12
rahulrv

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("")または類似のものに置き換えます。

17
Bart Kiers

@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, "");
13
Defuera

Retrofit rel.1.9はこの問題( https://github.com/square/retrofit/issues/854 )の影響を受けやすいようです。

それまでの間、現在のリリースが修正されるまでrel.1.6にダウングレードすることを検討してください。 rel.1.6にはこの特定のバグがないことが確認されています。

2
Eugene Karasev

_@Body String emptyBody_は、私が使用していたバックエンドサーバーとして機能せず、_Bad request_を返し、空の文字列を本文として受け入れませんでした。

空の文字列ではなく空のJSONを送信しました

@POST("/some/url) Observable<Thing> doThing(@Body JsonElement empty);

それから私はこのように私のメソッドを呼び出しました:

doThing(new JsonObject());

誰かが同様の問題を抱えている場合に役立つことを願っています。

0
Peter Moskala

okHttpをバージョン2.3.0にダウングレード

0
Andrei Tr.

@Postメソッドに含めるだけ

@Body String dummyValue、本文が不要な場合は、このクエリを記述して ""をサーバーに送信する必要があります

0
Out Of Bounds