3

Trying to send form data to the server via Retrofit but unable to request to the server. I want to post an image array with their data.

val builder: MultipartBody.Builder = MultipartBody.Builder().setType(MultipartBody.FORM);
builder.addFormDataPart("device_id",device_UDID)
builder.addFormDataPart("device_token",device_token)
builder.addFormDataPart("device_type","android")
builder.addFormDataPart("country_code",Constant.COUNTRY_CODE)
builder.addFormDataPart("email",signUpBean.email)
builder.addFormDataPart("mobile",signUpBean.phoneNumber)
builder.addFormDataPart("first_name",signUpBean.firstName)
builder.addFormDataPart("last_name",signUpBean.lastName)
builder.addFormDataPart("gender",signUpBean.gender)
builder.addFormDataPart("dob",signUpBean.dob)
builder.addFormDataPart("city",signUpBean.city)
builder.addFormDataPart("bike_type_id","1")
builder.addFormDataPart("bike_model",signUpBean.mfg)
builder.addFormDataPart("bike_manufacturer",signUpBean.mfg)
builder.addFormDataPart("reg_year",signUpBean.mfgYear)
builder.addFormDataPart("liecense_plate",signUpBean.licencePlateNo)
builder.addFormDataPart("bank_ac_name",signUpBean.bnkHolderName)
builder.addFormDataPart("bank_ac_number",signUpBean.bnkAccountNumber)
builder.addFormDataPart("bank_name",signUpBean.bnkName)
builder.addFormDataPart("bank_ifsc_code",signUpBean.ifscCode)
builder.addFormDataPart(
    "profile_pic",
    "profile" + ".jpg",
    RequestBody.create(MediaType.parse("image/*"), file_profile!!)
)
builder.addFormDataPart(
    "provider_documents[0][document]",
    "1" + ".jpg",
    RequestBody.create(MediaType.parse("image/*"), file_profile!!)
)
builder.addFormDataPart("provider_documents[0][document_id]","1")
builder.addFormDataPart("provider_documents[0][unique_id]","1")
builder.addFormDataPart("provider_documents[0][exprice_at]","2010-12-12")
val requestBody = builder.build()
observable = apiInterface.signUp2(requestBody)

I have tried many solutions but unable to post an image array with their data. When i remove provider_documents from addFormDataPart it works fine.

// @Multipart
@POST(URLHelper.register)
fun signUp2(@Body builder: RequestBody ): Observable<Registration>

How can I send Providers_document array and it is working fine on Postman.

enter image description here post this type of data from retrofit

val partMap = HashMap<String, RequestBody>()
partMap.put("device_id", createPartFromString(device_UDID));
partMap.put("device_token",createPartFromString(device_token))
partMap.put("device_type",createPartFromString("android"))
partMap.put("country_code",createPartFromString(Constant.COUNTRY_CODE))
partMap.put("email",createPartFromString(signUpBean.email))
partMap.put("mobile",createPartFromString(signUpBean.phoneNumber))
partMap.put("first_name",createPartFromString(signUpBean.firstName))
partMap.put("last_name",createPartFromString(signUpBean.lastName))
partMap.put("gender",createPartFromString(signUpBean.gender))
partMap.put("dob",createPartFromString(signUpBean.dob))
partMap.put("city",createPartFromString(signUpBean.city))
partMap.put("bike_type_id",createPartFromString("1"))
partMap.put("bike_model",createPartFromString(signUpBean.mfg))
partMap.put("bike_manufacturer",createPartFromString(signUpBean.mfg))
partMap.put("reg_year",createPartFromString(signUpBean.mfgYear))
partMap.put("liecense_plate",createPartFromString(signUpBean.licencePlateNo))
partMap.put("bank_ac_name",createPartFromString(signUpBean.bnkHolderName))
partMap.put("bank_ac_number",createPartFromString(signUpBean.bnkAccountNumber))
partMap.put("bank_name",createPartFromString(signUpBean.bnkName))
partMap.put("bank_ifsc_code",createPartFromString(signUpBean.ifscCode))

partMap.put(
    "provider_documents["+0+"][document_id]",
    createPartFromString(signUpBean.ifscCode)
)
partMap.put(
    "provider_documents["+0+"][unique_id]",
    createPartFromString(signUpBean.ifscCode)
)
partMap.put(
    "provider_documents["+0+"][exprice_at]",createPartFromString(signUpBean.dob)
)
    
val ImageMap = HashMap<String, MultipartBody.Part>()
ImageMap.put("profile_pic", prepareFilePart("12", file_profile!!));
ImageMap.put("provider_documents["+0+"][document]", prepareFilePart("1", file_profile!!));

Request Api

@Multipart
@POST(URLHelper.register)
fun signUp3(
    @PartMap photo: HashMap<String,
    RequestBody>,
    @PartMap ImageMap:HashMap<MultipartBody.Part>,
): Observable<Registration>
Farhana Naaz Ansari
  • 7,524
  • 26
  • 65
  • 105
  • Have u check this https://stackoverflow.com/q/34562950/7666442 && https://stackoverflow.com/a/35698175/7666442 – AskNilesh Jul 17 '19 at 10:53
  • @NileshRathod yes I have already checked it. – Farhana Naaz Ansari Jul 17 '19 at 10:54
  • Multipart working fine but I have stuck in image array with their data – Farhana Naaz Ansari Jul 17 '19 at 10:56
  • 1
    This should suffice https://stackoverflow.com/a/56707784/4377954. `MultipartBody.Part` is loaded in the loop for multiple images. You can put your format-data inside the same loop and increment the key. – Deˣ Jul 17 '19 at 10:57
  • @Deˣ yes I have already done it but I have ArrayList of type [here](https://stackoverflow.com/questions/38718439/passing-arrays-in-multipart-post-using-okhttp) and [here](https://stackoverflow.com/questions/40607862/retrofit-throwing-an-exception-java-lang-illegalargumentexception-only-one-en) – Farhana Naaz Ansari Jul 17 '19 at 11:01
  • @Deˣ I have already loaded the mulitple image with Multipart but how can I send id,exp_date along with the image that's why I made custom type but also failed to do it then i change to form type. – Farhana Naaz Ansari Jul 17 '19 at 11:04
  • @Farhana I have added an answer for you. Try similar approach. – Deˣ Jul 17 '19 at 11:13

2 Answers2

3

Dummy api interface.

 public interface ApiInterface {
        @Multipart
        @POST(URLHelper.register)
        Call<ModelProp> signUp2(@Part List<MultipartBody.Part> photos,
                          @PartMap Map<String, RequestBody> map;
    }

Now create data to post like this.

Map<String, RequestBody> partMap = new HashMap<>();
List<MultipartBody.Part> images = new ArrayList<>();
partMap.put("device_id", createPartFromString(deviceId)); // add data which are common for all images like device_id, device_token, device_type etc.
..
..

for (int i=0; i < upFileList.size(); i++){
   images.add(prepareFilePart("provider_documents["+i+"][document]", imageFile));
   partMap.add("provider_documents["+i+"][expires_at]", createPartFromString(expiry)); // add image specific data. 
 ...
 ..
}
...
..
observable = apiInterface.signUp2(images, partMap).

createPartFromString method

public RequestBody createPartFromString(String string) {
        return RequestBody.create(MultipartBody.FORM, string);
}

prepareFilePart method

private MultipartBody.Part prepareFilePart(String partName, File file){
    RequestBody requestBody = RequestBody.create(MediaType.parse("image/*"), file);

    return MultipartBody.Part.createFormData(partName, file.getName(),requestBody);
}
Deˣ
  • 4,191
  • 15
  • 24
0

Use it Like this:-

// @Multipart
@POST(URLHelper.register)
fun signUp2(@Part builder: MultipartBody ): Observable<Registration>

Updated :-

  private void uploadToServer(String filePath) {
        showProgressDialog();
        Retrofit retrofit = RetrofitClient.getRetrofitClient(this);
        ApiInterface uploadAPIs = retrofit.create(ApiInterface.class);
        File file = new File(filePath);
        //compressor.setDestinationDirectoryPath()
        RequestBody fileReqBody = RequestBody.create(MediaType.parse("image/*"), file);
        MultipartBody.Part part = MultipartBody.Part.createFormData("fileUpload", file.getName(), fileReqBody);
        //RequestBody description = RequestBody.create(MediaType.parse("text/plain"), "image-type");
        RequestBody imgNameReqBody = RequestBody.create(MediaType.parse("multipart/form-data"), "B2B_" + System.nanoTime());

        uploadAPIs.uploadImage(imgNameReqBody, part).enqueue(new Callback<UploadImageRespose>() {
            @Override
            public void onResponse(@NonNull Call<UploadImageRespose> call, @NonNull retrofit2.Response<UploadImageRespose> response) {
                if (response.isSuccessful() && response.body() != null) {
                    if (response.body().getCODE().equalsIgnoreCase("SUCCESS")) {
                        Toast.makeText(Activity.this, "Profile Image Upload Succesfully", Toast.LENGTH_SHORT).show();
                    } else {
                        hideProgressDialog();
                        Toast.makeText(Activity.this, "Some Error  occurred, try again", Toast.LENGTH_SHORT).show();
                    }
                } else {
                    hideProgressDialog();
                }

            }

            @Override
            public void onFailure(@NonNull Call<UploadImageRespose> call, @NonNull Throwable t) {
                Timber.d(TAG, t.getMessage());
                hideProgressDialog();
                Toast.makeText(Activity.this, "Some Error  occurred, try again", Toast.LENGTH_SHORT).show();
            }
        });
    }

add below method in your interface:-

    @Multipart
    @POST("Your Path Here")
    Call<UploadImageRespose> uploadImage(@Part("img_name") RequestBody img_name,
                                         @Part MultipartBody.Part file);