web-dev-qa-db-fra.com

Retrofit 2.0 en générant "IllegalArgumentException: les paramètres @Field ne peuvent être utilisés qu'avec le codage de formulaire". Comment faire une bonne requête API et la corriger?

Mon problème est que je ne sais pas comment utiliser Retrofit 2.0 avec les API reçues - mentionnées ci-dessous ...

Tout d'abord, j'ai besoin de nom d'utilisateur, mot de passe, fbID (facultatif), gmailID (facultatif), twitID (facultatif), sexe, date de naissance, emplacement (non requis - si long et lat a des valeurs), longitude (facultatif), latitude (facultatif) , profileImage (facultatif).

Quand tous les paramètres sont bons, recevez status = true. Sinon, recevez status = false Et les paramètres requis qui sont incorrects (par exemple, le courrier est déjà pris)

Ainsi, je peux recevoir status = true Ou status = false Et un tableau avec un maximum de 5 paramètres (nom d'utilisateur, email, mot de passe, sexe, date de naissance).

J'ai essayé ceci API Interface:

public interface AuthRegisterUserApi {
    @PUT()
    Call<AuthRegisterUserModel> getStatus(
            @Field("username") String username,
            @Field("email") String email,
            @Field("password") String password,
            @Field("fbID") String fbID,
            @Field("gmailID") String gmailID,
            @Field("twitID") String twitID,
            @Field("gender") String gender,
            @Field("birthDate") String birthDate,
            @Field("location") String location,
            @Field("longitude") String longitude,
            @Field("latitude") String latitude,
            @Field("profileImage") String profileImage
            );

    class Factory {
        private static AuthRegisterUserApi service;

        public static AuthRegisterUserApi getInstance() {
            Retrofit retrofit = new Retrofit.Builder()
                    .baseUrl(ApiConstants.REGISTER_URL)
                    .addConverterFactory(GsonConverterFactory.create())
                    .build();

            service = retrofit.create(AuthRegisterUserApi.class);

            return service;
        }
    }
}

avec ces modèles d'API (Pastebin.com)

et ce code dans Activity:

AuthRegisterUserApi.Factory.getInstance()
        .getStatus(
                usernameEditText.getText().toString(),
                emailEditText.getText().toString(),
                passwordEditText.getText().toString(),
                "", "", "",
                (maleRadioButton.isChecked() ? "male" : "female"),
                mYear + "-" + mMonth+1 + "-" + mDay,
                (geoLocationToggleButton.isChecked() ? geoLocationEditText.getText().toString() : ""),
                (!geoLocationToggleButton.isChecked() ? "50" : ""),
                (!geoLocationToggleButton.isChecked() ? "50" : ""),
                "")
        .enqueue(new Callback<AuthRegisterUserModel>() {
    @Override
    public void onResponse(Call<AuthRegisterUserModel> call, Response<AuthRegisterUserModel> response) {
        if(response.isSuccessful()) {
            if (response.body().isStatus()) {
                showToast(getApplicationContext(), "Registration ok.");
            } else {
                response.body().getInfo().getUsername();
            }
        }
    }

    @Override
    public void onFailure(Call<AuthRegisterUserModel> call, Throwable t) {

    }
});

J'ai une erreur: Java.lang.IllegalArgumentException: @Field parameters can only be used with form encoding. (parameter #1) for method AuthRegisterUserApi.getStatus

J'ai essayé d'enregistrer un utilisateur en utilisant Postman et cela fonctionne lorsque j'ai utilisé l'option Body -> x-www-form-urlencoded.

Comment puis-je créer une requête register vers cette API? Remplacez @Field Par quelque chose d'autre? J'ai toujours cette erreur ...

EDIT: Besoin de changer API Interface En ceci :

public interface AuthRegisterUserApi {
    @FormUrlEncoded
    @PUT("/api/register")
    Call<AuthRegisterUserModel> getStatus(
            @Field("username") String username,
            @Field("email") String email,
            @Field("password") String password,
            @Field("fbID") String fbID,
            @Field("gmailID") String gmailID,
            @Field("twitID") String twitID,
            @Field("gender") String gender,
            @Field("birthDate") String birthDate,
            @Field("location") String location,
            @Field("longitude") String longitude,
            @Field("latitude") String latitude,
            @Field("profileImage") String profileImage
            );

    class Factory {
        private static AuthRegisterUserApi service;

        public static AuthRegisterUserApi getInstance() {
            Retrofit retrofit = new Retrofit.Builder()
                    .baseUrl(ApiConstants.BASE_URL)
                    .addConverterFactory(GsonConverterFactory.create())
                    .build();

            service = retrofit.create(AuthRegisterUserApi.class);

            return service;
        }
    }
}

BASE_URL = http://ip_address:8400 Pour moi ...

Mais toujours erreur: Response.rawResponse = Response{protocol=http/1.1, code=400, message=Bad Request, url=http://ip_address:8400/api/register}. En utilisant Postman avec les mêmes données, j'ai reçu le code = 201 Créé. Je ne sais pas pourquoi ...

32
y07k2

Le problème était parce que j’essayais de PUT par exemple. longitude\latitude\location sans valeur - vide String.

Je veux dire - il y avait un problème du côté de l'API. Donc pour éviter que je change de méthode à ceci:

@FormUrlEncoded
@PUT(ApiConstants.REGISTER_URL_PART)
Call<RegisterModel> registerUser(
        @Field("username") String username,
        @Field("email") String email,
        @Field("password") String password,
        @Field("fbID") String fbID,
        @Field("gmailID") String gmailID,
        @Field("twitID") String twitID,
        @Field("gender") String gender,
        @Field("birthDate") String birthDate,
        @Nullable @Field("location") String location,
        @Nullable @Field("longitude") String longitude,
        @Nullable @Field("latitude") String latitude,
        @Field("profileImage") String profileImage
);

Maintenant, quand je ne fais aucune valeur pour l'un d'entre eux, je ne ferme tout simplement pas ce champ.

7
y07k2

Votre demande n'est pas correctement encodée, mais postier, alors changez cela:

@FormUrlEncoded
@PUT("/api/register")
    Call<AuthRegisterUserModel> getStatus(
            @Field("username") String username,
            @Field("email") String email,
            @Field("password") String password,
            @Field("fbID") String fbID,
            @Field("gmailID") String gmailID,
            @Field("twitID") String twitID,
            @Field("gender") String gender,
            @Field("birthDate") String birthDate,
            @Field("location") String location,
            @Field("longitude") String longitude,
            @Field("latitude") String latitude,
            @Field("profileImage") String profileImage);

Dis-moi si ça va.

33

tu viens de manquer @FormUrlEncoded au-dessus de votre appel de méthode de repos.

19
Rajesh.k

J'ai reçu un message d'erreur similaire et j'ai remarqué que, dans la définition de mon interface, j'avais manqué l'annotation @ForUrlEncoded - en plus de l'appel restant qui utilisera la partie de formulaire, ce qui semble être la même chose que lors du premier bloc de code envoyé. Jetez un coup d'oeil.

J'espère que cela t'aides.

2
Saulo Aguiar