1

I'm using retrofit for making API calls in my android app.Everything works fine with the GET requests ,but when I call the API with POST method and pass my custom object to it with @Body annotation ,the API doesn't receives the parameters passed.I tested the same API with same values in POSTMAN and I got the response.I've been using Retrofit for a while but not getting what exactly is happening in this case.Any help would be appreciated.

ApiInterface.java

@POST("User/login")
@Headers("x-api-key: 123456")
Call<LoginResponse> login(@Body LoginRequest loginRequest);

LoginRequest.java

public class LoginRequest {

@SerializedName("email")
@Expose
public String email;
@SerializedName("password")
@Expose
public String password;
@SerializedName("deviceType")
@Expose
public Integer deviceType;
@SerializedName("deviceId")
@Expose
public String deviceId;
@SerializedName("versionName")
@Expose
public String versionName;

public LoginRequest() {
}

public LoginRequest(String email, String password, Integer deviceType, String deviceId, String versionName) {
    super();
    this.email = email;
    this.password = password;
    this.deviceType = deviceType;
    this.deviceId = deviceId;
    this.versionName = versionName;
}
    //getters and setters

}

LoginResponse.java

public class LoginResponse {

@SerializedName("userId")
@Expose
private String userId;
@SerializedName("firstName")
@Expose
private String firstName;
@SerializedName("middleName")
@Expose
private Object middleName;
@SerializedName("lastName")
@Expose
private String lastName;
@SerializedName("email")
@Expose
private String email;
@SerializedName("phone")
@Expose
private String phone;
@SerializedName("userCompany")
@Expose
private String userCompany;
@SerializedName("userName")
@Expose
private String userName;
@SerializedName("userDesignation")
@Expose
private String userDesignation;
@SerializedName("companyName")
@Expose
private String companyName;
@SerializedName("photo")
@Expose
private Object photo;
@SerializedName("userType")
@Expose
private String userType;
@SerializedName("code")
@Expose
private String code;
@SerializedName("countryCode")
@Expose
private String countryCode;
@SerializedName("countryName")
@Expose
private String countryName;
@SerializedName("supervisor")
@Expose
private String supervisor;
@SerializedName("taskStatus")
@Expose
private Integer taskStatus;
@SerializedName("checkInStatus")
@Expose
private Integer checkInStatus;
@SerializedName("time")
@Expose
private String time;
@SerializedName("checkInPlace")
@Expose
private String checkInPlace;
@SerializedName("checkInId")
@Expose
private String checkInId;
@SerializedName("checkinDate")
@Expose
private String checkinDate;
@SerializedName("permission")
@Expose
private List<Permission> permission = null;

public LoginResponse() {
}

public LoginResponse(String userId, String firstName, Object middleName, String lastName, String email, String phone, String userCompany, String userName, String userDesignation, String companyName, Object photo, String userType, String code, String countryCode, String countryName, String supervisor, Integer taskStatus, Integer checkInStatus, String time, String checkInPlace, String checkInId, String checkinDate, List<Permission> permission) {
    super();
    this.userId = userId;
    this.firstName = firstName;
    this.middleName = middleName;
    this.lastName = lastName;
    this.email = email;
    this.phone = phone;
    this.userCompany = userCompany;
    this.userName = userName;
    this.userDesignation = userDesignation;
    this.companyName = companyName;
    this.photo = photo;
    this.userType = userType;
    this.code = code;
    this.countryCode = countryCode;
    this.countryName = countryName;
    this.supervisor = supervisor;
    this.taskStatus = taskStatus;
    this.checkInStatus = checkInStatus;
    this.time = time;
    this.checkInPlace = checkInPlace;
    this.checkInId = checkInId;
    this.checkinDate = checkinDate;
    this.permission = permission;
}

//getters and setters
}

ApiClient.java

public static Retrofit getClient() {
    if (retrofit == null) {
        retrofit = new Retrofit.Builder()
                .baseUrl(BASE_URL)
                .addConverterFactory(GsonConverterFactory.create())
                .build();
    }
    return retrofit;
}

POSTMAN screenshot

enter image description here

Neha
  • 389
  • 4
  • 8
  • 24

2 Answers2

0

Try this way :

 @FormUrlEncoded
 @Headers("x-api-key: 123456")
 @POST("User/login")
 Call<LoginResponse> login(@Field("email") email, @Field("password") password,@Field("deviceType") deviceType,@Field("deviceId") deviceId,@Field("versionName") versionName);
Oussema Aroua
  • 5,225
  • 1
  • 24
  • 44
0

In Postman you're sending form-data instead of raw that's why API is returning response. In Retrofit you're sending raw JSON request. I think that API accepts multipart/form-data. Just adjust the API interface like this,

import okhttp3.RequestBody;
import retrofit2.http.PartMap;
import retrofit2.http.Multipart;

@Multipart        //   <====== add this line
@POST("User/login")
@Headers("x-api-key: 123456")
Call<LoginResponse> login(@PartMap Map<String, RequestBody> params);  // change parameters 

And in activity/fragment adjust the code

Map<String, RequestBody> params = new HashMap<>();
params.put("email", RequestBody.create(MultipartBody.FORM, email));
params.put("password", RequestBody.create(MultipartBody.FORM, password));
params.put("deviceType", RequestBody.create(MultipartBody.FORM, String.valueOf(deviceType)));
params.put("deviceId", RequestBody.create(MultipartBody.FORM, deviceId));
params.put("versionName", RequestBody.create(MultipartBody.FORM, versionName));

YourApiInterface api = ...
Call<LoginResponse> call = api.login(params);   // pass it to method
call.enqueue(/* implementation */);

Please check (and understand) the difference between form-data, x-www-form-urlencoded and raw

Note: Please check the import statements and code comments properly.

Shashanth
  • 4,995
  • 7
  • 41
  • 51
  • Why need `MultipartBody.FORM` data? It only use when we need to upload image to server? – Piyush Jun 04 '19 at 05:15
  • Please check the screenshots of Postman. It clearly shows `form-data` not `x-www-form-urlencoded`. And also she's getting response for that request. So, I thought the server is accepting `form-data` – Shashanth Jun 04 '19 at 05:17
  • Thanks for your suggestions ,tried this and it is working. But I'm not getting one thing, there is no image data in request then why it was not working with @FormUrlEncoded header ? – Neha Jun 04 '19 at 05:24
  • @Neha Honestly, I don't have an idea. I think the API is configured to accept only `form-data`. I guessed it by looking into the screenshot of Postman. Yeah there're difference between these header types. Please check the URL included in my answer please go through it. – Shashanth Jun 04 '19 at 05:31