web-dev-qa-db-fra.com

Causée par: retrofit.RetrofitError: method POST doit avoir un corps de demande

J'utilise retrofit pour effectuer un appel post-api. J'obtiens l'erreur suivante tout en essayant de toucher le terminal.

     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)

essayer d'accéder à une api post

 @POST("/service/v2/auth/ip-address")
    rx.Observable<AuthState> verifyIP();

appel d'api

LoginService service = CKRestClient.get().create(LoginService.class);
            service.verifyIP().observeOn(AndroidSchedulers.mainThread()).subscribe(
                    new Action1<AuthState>() {
                        @Override
                        public void call(AuthState authState) {

                        }
                    });
        });
12
3xplore

Il semblerait que Retrofit souhaite que POST demandes aient une charge utile. Il y a déjà un problème pour cela: https://github.com/square/retrofit/issues/854

Pour contourner le problème, vous pouvez faire quelque chose comme ceci:

@POST("/service/v2/auth/ip-address")
rx.Observable<AuthState> verifyIP(@Body Object dummy);

et ensuite faire:

LoginService service = CKRestClient.get().create(LoginService.class);

service.verifyIP(null).observeOn(AndroidSchedulers.mainThread()).subscribe(
  new Action1<AuthState>() {
    @Override
    public void call(AuthState authState) {
      // ...
    }
  });
});

Ou, si service.verifyIP(null) jette un NPE, remplacez-le par service.verifyIP("") ou similaire.

17
Bart Kiers

J'ai résolu ce problème en remplaçant @Query par @Field, voici comment:

Code non fonctionnel:

@POST("/my/url/path")
Result postToServer(
        @Query("user_name") String userName);

Exemple de travail:

@FormUrlEncoded
@POST("/my/url/path")
Result postToServer(
        @Field("user_name") String userName);

Pour les méthodes qui n'ont pas de champs, j'ai dû ajouter une chaîne vide comme ci-dessous

Result postToServer(@Path("my_path") String myPath,
                               @Body String emptyString);

Et appelez ça passer "":

restClient.postToServer(myPath, "");
13
Defuera

Il semble que Retrofit rel.1.9 soit sujet au problème ( https://github.com/square/retrofit/issues/854 ).

En attendant, envisagez de passer à rel.1.6 jusqu'à ce que la version actuelle soit corrigée. Il est vérifié que rel.1.6 est exempt de ce bogue particulier.

2
Eugene Karasev

@Body String emptyBody ne fonctionnait pas pour moi en tant que serveur principal avec lequel je travaillais, renvoyait Bad request et n'acceptait pas la chaîne vide en tant que corps.

Je viens d'envoyer JSON vide au lieu de String vide

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

et puis je viens d'appeler ma méthode comme ceci:

doThing(new JsonObject());

J'espère que cela aidera si quelqu'un a un problème similaire.

0
Peter Moskala

rétrograder OkHttp à la version 2.3.0

0
Andrei Tr.

il suffit d'inclure dans la méthode @Post

@Body String dummyValue, si le corps n'est pas requis, vous devez écrire cette requête et envoyer "" au serveur.

0
Out Of Bounds