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[]).
Using postman I'm setting the parameters and the files as:
first-parameter=text content
second-parameter=text content
files[0]={first selected file}
files[1]={second selected file}
Submitting this request on postman is always successful, and the files are uploaded successfully.
When I generate code snippets on postman, this is the result:
POST /api/*******/new HTTP/1.1
Host: ***.***.***.*** ip-address
Authorization: {authorization header}
Cache-Control: no-cache
Postman-Token: d15f13f1-4a65-81d1-bf91-f5accd1b1dd0
Content-Type: multipart/form-data; boundary=----WebKitFormBoundary7MA4YWxkTrZu0gW
------WebKitFormBoundary7MA4YWxkTrZu0gW
Content-Disposition: form-data; name="first-parameter"
first-parameter-value
------WebKitFormBoundary7MA4YWxkTrZu0gW
Content-Disposition: form-data; name="second-parameter"
second-parameter-value
------WebKitFormBoundary7MA4YWxkTrZu0gW
Content-Disposition: form-data; name="files[0]"; filename=""
Content-Type:
------WebKitFormBoundary7MA4YWxkTrZu0gW
Content-Disposition: form-data; name="files[1]"; filename=""
Content-Type:
------WebKitFormBoundary7MA4YWxkTrZu0gW--
On Android, I'm using Retrofit with the HttpLoggingInterceptor libraries, and using the @PartMap annotation when posting the request:
//API Definition:
interface ApiDefinitions {
@Multipart
@POST("*******/new")
Call<ApiResponse> submitNew(@Header("Authorization") String authHeader,
@PartMap Map<String, RequestBody> params);
}
//Preparing and sending the request code:
public void postContent() {
HttpLoggingInterceptor interceptor = new HttpLoggingInterceptor();
interceptor.setLevel(HttpLoggingInterceptor.Level.BODY);
OkHttpClient client = new OkHttpClient
.Builder()
.addInterceptor(interceptor)
.build();
Retrofit retrofit = new Retrofit
.Builder()
.baseUrl(API_URL)
.client(client)
.addConverterFactory(GsonConverterFactory.create(new Gson()))
.build();
ApiDefinitions api = retrofit.create(ApiDefinitions.class);
MediaType mediaType = MediaType.parse("multipart/form-data");
Map<String, RequestBody> params = new HashMap<>();
params.put("first-parameter", MultipartBody.create(mediaType, "first-parameter-value"));
params.put("second-parameter", MultipartBody.create(mediaType, "second-parameter-value"));
params.put("files[0]", MultipartBody.create(mediaType, new File("First file path")));
params.put("files[1]", MultipartBody.create(mediaType, new File("Second file path")));
Call<ApiResponse> call = api.submitNew("Auth Token", params);
enqueue.enqueue(new Callback<ApiResponse>() {
@Override
public void onResponse(Call<ApiResponse> call, Response<ApiResponse> response) {
}
@Override
public void onFailure(Call<ApiResponse> call, Throwable t) {
}
});
}
Submitting this request works with no errors, http response is 200, But the files are not uploaded !!!
Since I'm using the HttpLoggingInterceptor, I've tried comparing the retrofit logs with post man code snippets, this is the retrofit log:
D/OkHttp: --> POST http://{api_address}/api/*****/new http/1.1
D/OkHttp: Content-Type: multipart/form-data; boundary=64360751-a7f4-44c4-a008-f5de764c7298
D/OkHttp: Content-Length: 119325
D/OkHttp: Authorization: {Authorization-Token}
D/OkHttp: --64360751-a7f4-44c4-a008-f5de764c7298
D/OkHttp: Content-Disposition: form-data; name="first-parameter"
D/OkHttp: Content-Transfer-Encoding: binary
D/OkHttp: Content-Type: multipart/form-data; charset=utf-8
D/OkHttp: Content-Length: 10
D/OkHttp: first-parameter-value
D/OkHttp: --64360751-a7f4-44c4-a008-f5de764c7298
D/OkHttp: Content-Disposition: form-data; name="second-parameter"
D/OkHttp: Content-Transfer-Encoding: binary
D/OkHttp: Content-Type: multipart/form-data; charset=utf-8
D/OkHttp: Content-Length: 10
D/OkHttp: second-parameter-value
D/OkHttp: --64360751-a7f4-44c4-a008-f5de764c7298
D/OkHttp: Content-Disposition: form-data; name="files[0]"
D/OkHttp: Content-Transfer-Encoding: binary
D/OkHttp: Content-Type: multipart/form-data;
D/OkHttp: Content-Length: 44205
D/OkHttp: ?PNG
D/OkHttp:
D/OkHttp: ??????IHDR????????????????????r?B???????sBIT??O????? ??IDATx?4??mYv??}c?9???so?|W???R??2z?T%?8B?X?
D/OkHttp: &?D$??B??r?D??w?!@????????{??H???[?!,?@ ?4h?P????>?A??&? ????B?[?,?fD?Mi?d?5)???5?{??-?MQt???&
D/OkHttp: --64360751-a7f4-44c4-a008-f5de764c7298
D/OkHttp: Content-Disposition: form-data; name="files[1]"
D/OkHttp: Content-Transfer-Encoding: binary
D/OkHttp: Content-Type: multipart/form-data;
D/OkHttp: Content-Length: 44205
D/OkHttp: ?PNG
D/OkHttp:
D/OkHttp: ??????IHDR????????????????????r?B???????sBIT??O????? ??IDATx?4??mYv??}c?9???so?|W???R??2z?T%?8B?X?
D/OkHttp: &?D$??B??r?D??w?!@????????{??H???[?!,?@ ?4h?P????>?A??&? ????B?[?,?fD?Mi?d?5)???5?{??-?MQt???&
D/OkHttp: --64360751-a7f4-44c4-a008-f5de764c7298--
D/OkHttp: --> END POST (119325-byte body)
D/OkHttp: <-- 200 OK http://{api_address}/api/*****/new (3409ms)
I've tried to find what's wrong in my request by comparing both logs from postman vs retrofit, but I can't find it !
The random boundary strings are different which is normal, postman uses webkit, while retrofit does not ! I don't think this is an issue at all.
I've tried to use @Part List<MultipartBody.Part
instead of @PartMap Map<String, RequestBody>
for the files as suggested here, but it didn't work also.
What should I do for the files to be uploaded ?
See Question&Answers more detail:
os