Retrofit 2.0 throwing "IllegalArgumentException: параметры @Field могут использоваться только с кодировкой формы". Как сделать правильный запрос API и исправить его?

Моя проблема в том, что я не знаю, как начать использовать Retrofit 2.0 с принятым API, упомянутым ниже...

Во-первых, мне нужно указать имя пользователя, пароль, fbID (необязательно), gmailID (необязательно), twitID (необязательный), пол, дату рождения, местоположение (не требуется - если long и lat имеет значения), долгота (необязательно), широта (необязательно), profileImage (необязательно).

Когда все параметры хороши - получите status = true. Если нет - получите status = false и требуемые параметры, которые являются неправильными (например, почта уже выполнена)

Поэтому я могу получить status = true или status = false и массив с максимальными 5 параметрами (имя пользователя, адрес электронной почты, пароль, пол, дата рождения).

Я пробовал это 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;
        }
    }
}

с помощью этих моделей API (Pastebin.com)

и этот код в 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) {

    }
});

У меня есть ошибка: java.lang.IllegalArgumentException: @Field parameters can only be used with form encoding. (parameter #1) for method AuthRegisterUserApi.getStatus

Я попытался зарегистрировать пользователя с помощью Postman, и он работает, когда я использовал опцию Bodyx-www-form-urlencoded.

Как я могу создать запрос я register к этому API? Изменить @Field на что-то еще? У меня всегда есть эта ошибка...

EDIT: нужно изменить API Interface на:

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 для меня...

Но все еще появилась ошибка: Response.rawResponse = Response{protocol=http/1.1, code=400, message=Bad Request, url=http://ip_address:8400/api/register}. Используя Postman с теми же данными, я получил код = 201 Created. Не знаю, почему...

Ответы

Ответ 1

Проблема заключалась в том, что я пытаюсь выполнить PUT, например. longitude\latitude\location без значения - пусто String.

Я имею в виду - возникла проблема со стороны API. Поэтому, чтобы избежать этого, я изменил метод:

@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
);

Теперь, когда я не получаю значения для одного из них, я просто не добавляю это поле.

Ответ 2

Ваш запрос не закодирован правильно, но почтальон, так что измените его:

@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);

Скажите, хорошо ли это.

Ответ 3

вы просто пропустили @FormUrlEncoded над вызовом метода Rest.

Ответ 4

У меня появилось подобное сообщение об ошибке, и я заметил, что в своем определении интерфейса я пропустил аннотацию @ForUrlEncoded - поверх остального вызова, который будет использовать часть формы, которая, похоже, та же самая, что вы сделали при первом опубликованном кодовый блок. Взгляните на это.

Надеюсь, что это поможет.