'Don't want to send file but retrofit doesn't allow null

I'm sending raw data along with a file using retofit. When I send file it works perfectly but if I don't want to send file and pass null instead app crashes.

MyInterfcace.class

public interface MainInterface {
 @POST("contact/updateWithFile")
Call<AddCustomerModel> updateCustomerWithFile(@Body RequestBody data);
  }

Api Call

private void updateCustomerWithFiles(JSONObject obj) {
    progressBarHandler.show();


    MultipartBody.Builder builder = new MultipartBody.Builder();
    builder.setType(MultipartBody.FORM);

    builder.addFormDataPart("bodyData", String.valueOf(obj));

    if (parts.size() > 0) {
        for (int i = 0; i < parts.size(); i++) {
            File file = new File(parts.get(i));
            builder.addFormDataPart("uploadingFiles", file.getName(), RequestBody.create(MediaType.parse("multipart/form-data"), file));
        }
    } else {
        File f = null;
        builder.addFormDataPart("uploadingFiles", "", RequestBody.create(MediaType.parse("multipart/form-data"), f));
    }


    File file = new File("");

    MultipartBody requestBody = builder.build();

    MainInterface apiService = ApiClient.getClient().create(MainInterface.class);

    Call<AddCustomerModel> call = apiService.updateCustomerWithFile(requestBody);

    call.enqueue(new Callback<AddCustomerModel>() {
        @Override
        public void onResponse(Call<AddCustomerModel> call, Response<AddCustomerModel> response) {
            progressBarHandler.dismiss();
            if (response.isSuccessful()) {
                finish();
                overridePendingTransition(0, 0);
            } else {
                Log.d("TAG", "No Data!!!");
            }
        }

        @Override
        public void onFailure(Call<AddCustomerModel> call, Throwable t) {
            progressBarHandler.dismiss();
        }
    });
}

How can I solve this?



Solution 1:[1]

Retrofit will not allow null for the @Body, and this is an intended behavior,

From the issue discussion,

When you omit a body param we send an empty body with no content type.

If you want to know more about why this decision was taken then take a look into the issue discussed in square's github,

https://github.com/square/retrofit/issues/1488

Solution 2:[2]

Have two retrofit calls as below

@Multipart
@POST("some_route")
Call<JsonObject> sendWithFile(@Query("item_id") String itemId,
                              @Query("item_name") String itemName,
                              @Part MultipartBody.Part[] files);

@POST("some_route")
Call<JsonObject> editVideoWithoutVideo(@Query("item_id") String videoId,
                                        @Query("item_name") String itemName);

Then Call Them Like This

Call<JsonObject> call;
if (mpFiles == null) {

    call = RetrofitClientLaravel.getInstance(mContext)
                                .sendWithoutFile(itemId,
                                                 itemName);

} else {

    call = RetrofitClientLaravel.getInstance(mContext)
                                .sendWithFile(itemId,
                                              itemName,
                                              mpFiles);
}

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1 MRah
Solution 2 DragonFire