Android Upload Multiple Files In A Single Request

后端 未结 2 1622
不知归路
不知归路 2021-01-21 03:34

I\'m posting content to the server in a multipart/form-data request. and the data I\'m posting contains multiple parameters including a file array parameter (files[]).

相关标签:
2条回答
  • 2021-01-21 03:51

    I think you should change the MediaType for file. and you also check the link for that https://futurestud.io/tutorials/retrofit-2-how-to-upload-files-to-server and for send file with @Part MultipartBody.Part

    MediaType mediaTypeForText = MediaType.parse("text/plain"); 
    MediaType mediaTypeForImage = MediaType.parse("image/*");
    
    Map<String, RequestBody> params = new HashMap<>(); 
    params.put("first-parameter", MultipartBody.create(mediaTypeForText, "first-parameter-value")); 
    params.put("second-parameter", MultipartBody.create(mediaTypeForText, "second-parameter-value")); 
    params.put("files[0]", MultipartBody.create(mediaTypeForImage, new File(fileUri.getPath())); 
    params.put("files[1]", MultipartBody.create(mediaTypeForImage, new File(fileUri.getPath()));
    
    0 讨论(0)
  • 2021-01-21 04:03

    First of all, I've been doing one thing wrong which is using a @PartMap Map<String, RequestBody> in the ApiDefinitions interface.

    In case you're doing a post request with multiple parameters and multiple files, always make sure when defining the api method to use RequestBody for non-file parameters, and use MultipartBody.Part for file parameters.

    In my case I needed to send an array of files, so the parameter that has worked for me is MultipartBody.Part[].

    This is the new api definition :

    @Multipart
    @POST("*******/new")
    Call<ApiResponse> submitNew(@Header("Authorization") String authHeader,
                                              @Part("first-parameter") RequestBody firstParameter,
                                              @Part("first-parameter") RequestBody secondParameter,
                                              @Part MultipartBody.Part[] files);
    

    The second mistake I made was not noticing this:

    PostMan Log: Content-Disposition: form-data; name="files[0]"; filename=""

    Retrofit Log: Content-Disposition: form-data; name="files[0]"

    The filename was not included in the multipart request, which apparently is a known issue when uploading files to a php service !

    I didn't make the api, and I don't have any php background so please don't judge me. As far as I know, I was successfully sending files to the service api, but the api didn't know how to save these files !

    So when sending the request:

    List<Uri> files; //These are the uris for the files to be uploaded
    MediaType mediaType = MediaType.parse("");//Based on the Postman logs,it's not specifying Content-Type, this is why I've made this empty content/mediaType
    MultipartBody.Part[] fileParts = new MultipartBody.Part[files.size()];
    for (int i = 0; i < files.size(); i++) {
        File file = new File(files.get(i).getPath());
        RequestBody fileBody = RequestBody.create(mediaType, file);
        //Setting the file name as an empty string here causes the same issue, which is sending the request successfully without saving the files in the backend, so don't neglect the file name parameter.
        fileParts[i] = MultipartBody.Part.createFormData(String.format(Locale.ENGLISH, "files[%d]", i), file.getName(), fileBody);
    }
    
    Call<ApiResponse> call = api.submitNew("Auth Token", MultipartBody.create(mediaType, "first_parameter_values"), MultipartBody.create(mediaType, "second_parameter_values"), fileParts);
    
    call.enqueue(new Callback<ApiResponse>() {
    
        @Override
        public void onResponse(Call<ApiResponse> call, Response<ApiResponse> response) {
        }
    
        @Override
        public void onFailure(Call<ApiResponse> call, Throwable t) {
        }
    });
    
    0 讨论(0)
提交回复
热议问题