Send Form data to server in Retrofit

2019-08-20 14:39发布

问题:

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.

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>

回答1:

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


回答2:

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