Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

error with more than one @Body field - retrofit2 beta3

I am just starting out with retrofit for android. I am getting an error when I try to specify 2 fields for the body of a post request:

Multiple @Body method annotations found. (parameter #2) for method

The Call is defined in my API interface file as:

@POST("auth/login")
Call<UserData> login(@Body String username, @Body String password);

And I create the call with:

Retrofit retrofit = new Retrofit.Builder()
            .baseUrl(baseURL)
            .addConverterFactory(GsonConverterFactory.create())
            .build();

APIService service = retrofit.create(APIService.class);
Call<UserData> call = service.login(username, password);

error is generated when the call is created (do not have a chance to execute it). When I remove one of the body fields it seems to work fine.

Any Ideas?

like image 802
chriselderer Avatar asked Jan 08 '16 00:01

chriselderer


2 Answers

Using multiple @Body is bad idea, because @Body here means message Body of HTML POST.

(Detail: How to send data in the HTTP request body when using an HTML form?)

I suggest you to define a class containing both username and password, like below.

public class LoginInformation {
    String username;
    String password;
}

And, fill your information on that class instance, and use that.

@POST("auth/login")
Call<UserData> login(@Body LoginInformation loginInformation);
like image 193
Stanley Ko Avatar answered Nov 10 '22 00:11

Stanley Ko


Any HTTP request is allowed to contain only one message body , if you try adding two @Body parameters you will get this message "Multiple @Body method annotations found."

And you can fix it by following this:

You can send multiple or different type of objects at the same time using HashMap or single type, for example:

HashMap<String, Object> map = new HashMap<>();
map.put("password", "123456");
map.put("username", "Jake Warthon");

or

public class User(){
    private String username;
    private String password;

    public void setUsername(String username){
        this.username = username;
    }

    public void setPassword(String password){
        this.password = password;
    }
}

User user = new User(); 
user.setUsername("Jake Warthon")
user.setPassword("123456");
map.put("user", user);

You can append more data (like different type of objects) in a single body if you want (optional)

map.put("user", user);
map.put("authorization", "12uh3u12huhcd2");
map.put("something", someobject);

You have to change the body type of the request to receive a Hashmap or User

@POST("auth/login")
Call<UserData> login(@Body HashMap map);

or

@POST("auth/login")
Call<UserData> login(@Body User user);

Finally you pass the data to service like you already did.

Call<UserData> call = service.login(map); 

or

Call<UserData> call = service.login(user); 

And remember, the server side have to implement it correctly to receive the data as a map.

like image 24
diogojme Avatar answered Nov 10 '22 01:11

diogojme