Upload file using both Multipart and JSON Key value pairs with Retrofit2

Ranjit :

Currently we are uoloading files (Video, Audio, Text etc..) by converting String bytes with simple JSON including some other values with their Key-Value pairs. Just like below:

Some header values:

{
    "header": {
        "geoDate": {
            "point": {
                "longitude": 77.56246948242188,
                "latitude": 12.928763389587403
            },
            "date": "2020-02-25T18:26:00Z"
        },
        "version": "1.35.00.001",
        "businessId": "178"
    }
}

and files info:

    JSONObject data = new JSONObject();
    data.put("name", params.name);
    data.put("mimeType", params.mimeType);
    data.put("fileSize", params.fileSize);
    data.put("inputData", params.data);

    requestJSON.put("data", data);

Here params.data is a simple conversion of bytes String bytes = Base64.encodeToString(bos.toByteArray(), Base64.DEFAULT);

It's working but we want to do it through Retrofit by sending the files through MultiPart to the server and which will improve the performance as well. But the problem is as it was in the JSON structure, the server can't change its program and we (app) only have to do something which sends the file using Retrofit Multipart including other values and keys(inputData also).

I am searching for a way to do that. And I am wondering if we are able to send also, is the server has to change anything for the API structure like currently its accepting String for the bytes and we are going to change it to file for inputData.

Eduard Dubilyer :

Works fine for me (it's my code, just adapt it to your business logic):

Interface:

@Multipart
@POST("{projectName}/log")
Call<LogRp> uploadFile(
        @Path("projectName") String project,
        @PartMap Map<String, RequestBody> mp,
        @Part MultipartBody.Part file
        );

Service:

private MultipartBody.Part buildFilePart(File file, FileType type) {
    return MultipartBody.Part.createFormData("file", file.getName(),
            RequestBody.create(MediaType.parse(type.value.get()), file));
}

private Map<String, RequestBody> buildJsonPart(LogRq logRq) throws JsonProcessingException {
    return Collections.singletonMap("json_request_part", RequestBody.create(
            MediaType.parse("application/json"),
            new ObjectMapper().writeValueAsString(logRq))
    );
}

And then simply:

client.uploadFile(
                        project,
                        buildJsonPart(logRq),
                        buildFilePart(file, type)
                )

LogRp and LogRq are Response and Request POJOs. ping me if help needed.

Guess you like

Origin http://43.154.161.224:23101/article/api/json?id=24347&siteId=1