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, и он работает, когда я использовал опцию Body
→ x-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 - поверх остального вызова, который будет использовать часть формы, которая, похоже, та же самая, что вы сделали при первом опубликованном кодовый блок. Взгляните на это.
Надеюсь, что это поможет.