How to convert Map<String, String> to RequestBody?

Viewed 4249

Using Retrofit 2.4.0, I am making a @Multipart @POST request. I am sending a file as @Part along with some metadata as@PartMap. This is what the call looks like.

@Multipart
@POST("https://8hoot.com/my-path")
Single<Response<UploadMediaResponseModel>> uploadMedia(
        @PartMap Map<String, RequestBody> metadata,
        @Part MultipartBody.Part filePart
);

There is another Map<String, String>, let us call it subMetaMap, which contains related key-value pairs.

How can I store this subMetaMap in the @PartMap metadata? Something like shown below.

RequestBody subMetaMapAsRequestBody; // Convert subMetaMap to RequestBody
metadata.put("subMeta", subMetaMapAsRequestBody);

Currently, I am using the following method.

for (String s : subMetaMap.keySet()) {
    RequestBody requestBody = RequestBody.create(MultipartBody.FORM, subMetaMap.get(s));
    metadata.put(s, requestBody);
}

This is not the desired solution as I want the whole subMetaMap as the RequestBody not its individual key-value pairs


Edit 1- The backend team doesn't take different MIME types during Multipart request. So sending JSON, MessagePack, etc. is not an option.

2 Answers

Let's assume you have following map you want to send this data to retrofit request body

HashMap<String, String> map = new HashMap<>();
map.put("key1", "value1");
map.put("key2", "value2");
map.put("key3", "value3");
map.put("key4", "value4");

Following is the URL Request method:

@FormUrlEncoded
@POST("/yourapiname")
Call<ResponseObj> methodName(@FieldMap HashMap<String, String> yourHasMapObject);

If you want to add file and hashmap then use the following method:

@Multipart
@POST("yourapiname")
Call<ResponseObj> methodName(@HeaderMap HashMap<String, String> yourHasMapObject, @Part MultipartBody.Part file);

You should pass the other map in the same way you are passing the first map.

First, convert the values of second map from String to RequestBody and then your request should be like follows:

@Multipart
@POST("https://8hoot.com/my-path")
Single<Response<UploadMediaResponseModel>> uploadMedia(
        @PartMap Map<String, RequestBody> metadata,
        @PartMap Map<String, RequestBody> anotherMetaData,
        @Part MultipartBody.Part filePart
);
Related