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[]).
First of all, I've been doing one thing wrong which is using a @PartMap Map 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 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 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 call = api.submitNew("Auth Token", MultipartBody.create(mediaType, "first_parameter_values"), MultipartBody.create(mediaType, "second_parameter_values"), fileParts);
call.enqueue(new Callback() {
@Override
public void onResponse(Call call, Response response) {
}
@Override
public void onFailure(Call call, Throwable t) {
}
});