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) {
}
});
});
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.
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, "");
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.
@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.
rétrograder OkHttp à la version 2.3.0
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.