Retrofit 2.0 throwing "IllegalArgumentException: @Field parameters can only be used with form encoding". How to do right API query and fix it?
Solution 1
The problem was because I try to PUT
e.g. longitude
\ latitude
\ location
with no value - empty String
.
I mean - there was a problem on API side. So to avoid that I changed method to this:
@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
);
Now, when I go no value for one of them, I simply don't enclose this field.
Solution 2
you just missed @FormUrlEncoded
above your Rest method call.
Solution 3
Your request is not encoded right, but are postman, so do change that :
@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);
Tell me if it's ok.
Solution 4
I got a similar error message and I noticed that in my interface definition I missed the @ForUrlEncoded annotation - on top of the rest call that will use the form part, which seems to be the same thing you did at the first posted code block. Take a look at it.
Hope this helps.
y07k2
BY DAY: Java Developer at work. Android Developer at home. BY NIGHT: I'm interested in sport (especially football), new technologies and mobile phones. FOR FUN: Playing FIFA 17 with friends, watching football matches (EPL, UCL and Polish Ekstraklasa) and play football with mates.
Updated on August 01, 2022Comments
-
y07k2 over 1 year
My problem is that I don't know how to start using Retrofit 2.0 with received API - mentioned below...
Firstly, I need to username, password, fbID (optional), gmailID (optional), twitID (optional), gender, birthDate, location (not required - if long and lat has values), longitude (optional), latitude (optional), profileImage (optional).
When all parameters are good - receive
status = true
. If not - receivestatus = false
and required parameters which are wrong (e.g. mail is already taken)So I can receive
status = true
orstatus = false
and array with max 5 parameters (username, email, password, gender, birthDate).I tried this
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; } } }
with this API models (Pastebin.com)
and this code in
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) { } });
I have error:
java.lang.IllegalArgumentException: @Field parameters can only be used with form encoding. (parameter #1) for method AuthRegisterUserApi.getStatus
I tried to register user using Postman and it works when I used option
Body
->x-www-form-urlencoded
.How can I create I
register
query to this API? Change@Field
to something else? I have got this error always...EDIT: Need to change
API Interface
to this: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
for me...But still got error:
Response.rawResponse = Response{protocol=http/1.1, code=400, message=Bad Request, url=http://ip_address:8400/api/register}
. Using Postman with the same data I received code=201 Created. Don't know why... -
y07k2 almost 8 years
Response.rawResponse = Response{protocol=http/1.1, code=400, message=Bad Request, url=http://ip_address:8400/api/register}
. Co this is not working. -
Raphael Teyssandier almost 8 yearsYou are sure, that your request is a put and not a post ?
-
Raphael Teyssandier almost 8 yearsHave try with a different arguments ? Because since you put him in the database you can't reput him ?
-
y07k2 almost 8 yearsTrying with different params on app first - response null; on Postman - response
status = true
. Mindblow... -
Raphael Teyssandier almost 8 yearsOkay, that's weird, on postman the endpoint is register/ or register ?
-
y07k2 almost 8 years
register
, without slash "/" -
y07k2 almost 8 years
POST
method is working. ButPUT
method is working when I removedresponse.isStatus()
fromonResponse() method
... Trying to change status to String, still response null when usingresponse.isStatus()
... -
Arhat Baid about 7 yearsYou saved me, man!!! Thanks a ton.By mistake, I deleted this line and was facing this error.