【问题标题】:Retrofit getting empty parameters from POST call改造从 POST 调用中获取空参数
【发布时间】:2019-10-19 01:32:23
【问题描述】:

我正在使用改造在我的 android 应用程序中进行 API 调用。GET 请求一切正常,但是当我使用 POST 方法调用 API 并使用 @Body 注释将我的自定义对象传递给它时,API 没有t 接收传递的参数。我在 POSTMAN 中用相同的值测试了相同的 API,我得到了响应。我已经使用 Retrofit 有一段时间了,但没有得到在这种情况下到底发生了什么。任何帮助将不胜感激。

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;
}

邮递员截图

【问题讨论】:

  • 错误是什么?一定有什么错误
  • 我在api中打印了参数,json是空的。没有错误
  • 你添加了addConverterFactory吗?
  • 不,还没有。我试试看。
  • @Piyush 正如你所建议的,我添加了 GsonConverterFactory 但问题仍然存在

标签: android post retrofit


【解决方案1】:

在 Postman 中,您发送的是 form-data 而不是 raw,这就是 API 返回响应的原因。在 Retrofit 中,您发送 raw JSON 请求。我认为 API 接受multipart/form-data。只需像这样调整API接口,

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 

并在活动/片段中调整代码

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 */);

请检查(并理解)form-data, x-www-form-urlencoded and raw 之间的区别

注意:请正确检查导入语句和代码cmets。

【讨论】:

  • 为什么需要MultipartBody.FORM 数据?只有当我们需要上传图片到服务器时才使用?
  • 请查看 Postman 的截图。它清楚地显示form-data 而不是x-www-form-urlencoded。她也收到了对该请求的回应。所以,我认为服务器正在接受form-data
  • 感谢您的建议,试过了,效果很好。但我没有得到一件事,请求中没有图像数据那么为什么它不能与 @FormUrlEncoded 标头一起使用?
  • @Neha 老实说,我不知道。我认为 API 配置为仅接受 form-data。我通过查看 Postman 的屏幕截图猜到了。是的,这些标头类型之间存在差异。请检查我的答案中包含的 URL,请通过它。
【解决方案2】:

试试这个方法:

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

【讨论】:

  • 她想发送自定义数据
  • 可能和encode类型有关,所以她需要改一下,是的,我的解决方法是用post发送数据,问题出在哪里?
  • @OussemaAroua 我也尝试过使用这种方法,但同样的事情正在发生
猜你喜欢
  • 2015-05-14
  • 2018-01-29
  • 2016-03-07
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-01-19
相关资源
最近更新 更多