Kwang Yeon Gil
Kwang Yeon Gil

Reputation: 11

Uploading multipart/form-data on Android using OKHttp

I was trying to upload Multipart/form-data on Android using Okhttp, but it does not work.

The request header is

POST /api/texttospeech/v3.0-beta1//datasets/upload HTTP/1.1 Host: koreacentral.customvoice.api.speech.microsoft.com Connection: keep-alive Content-Length: 201455 Accept: application/json, text/plain, / Correlation-Id: 290c5850-f621-11ea-ac4a-9dac0e19cc7b User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/85.0.4183.102 Safari/537.36 Edg/85.0.564.51 Ocp-Apim-Subscription-Key: 38fae10960fc477ba614c6dfe64613ba Content-Type: multipart/form-data; boundary=----WebKitFormBoundaryZAaHsREIpzJ9sBHS Origin: https://speech.microsoft.com Sec-Fetch-Site: same-site Sec-Fetch-Mode: cors Sec-Fetch-Dest: empty Accept-Encoding: gzip, deflate, br Accept-Language: ko,en;q=0.9,en-US;q=0.8

and the multipart/form-data is

------WebKitFormBoundaryZAaHsREIpzJ9sBHS Content-Disposition: form-data; name="projectId"

1a685f5d-400b-4801-8adb-9d359cad27cb ------WebKitFormBoundaryZAaHsREIpzJ9sBHS Content-Disposition: form-data; name="name"

16151 ------WebKitFormBoundaryZAaHsREIpzJ9sBHS Content-Disposition: form-data; name="description"

51561 ------WebKitFormBoundaryZAaHsREIpzJ9sBHS Content-Disposition: form-data; name="dataImportKind"

CustomVoice ------WebKitFormBoundaryZAaHsREIpzJ9sBHS Content-Disposition: form-data; name="locale"

en-US ------WebKitFormBoundaryZAaHsREIpzJ9sBHS Content-Disposition: form-data; name="properties"

{"Gender":"Male","IsMixLingual":"false","PortalAPIVersion":"3"} ------WebKitFormBoundaryZAaHsREIpzJ9sBHS Content-Disposition: form-data; name="audiodata"; filename="1.zip" Content-Type: application/x-zip-compressed

------WebKitFormBoundaryZAaHsREIpzJ9sBHS Content-Disposition: form-data; name="transcriptions"; filename="transcript.txt" Content-Type: text/plain

------WebKitFormBoundaryZAaHsREIpzJ9sBHS--

The code I created is something like this.

String boundary = "----WebKitFormBoundary" + result; //result is the random digits

        String Url = String.format("https://%s.customvoice.api.speech.microsoft.com/api/texttospeech/v3.0-beta1//datasets/upload", region);
        String audioPath = getFilesDir().getAbsolutePath()+"/audios.zip";
        String scriptPath = getFilesDir().getAbsolutePath()+"/script.txt";

        System.out.println("properties to String"+ properties.toString());

        File audioFile = new File(audioPath);
        File scriptFile = new File(scriptPath);
        //Create request body (params or json)
        System.out.println("audiopath is " + audioPath);
        System.out.println("scriptpath is "+ scriptPath);

        MultipartBody formBody = new MultipartBody.Builder(boundary)
                .setType(MultipartBody.FORM)
                .addFormDataPart("projectId", projectId)
                .addFormDataPart("name", defaultVal)
                .addFormDataPart("description", defaultVal)
                .addFormDataPart("dataImportKind", "CustomVoice")
                .addFormDataPart("locale", "en-US")
                .addFormDataPart("properties", properties.toString())
                .addFormDataPart("audiodata", "audios.zip", RequestBody.create(MediaType.parse("application/x-zip-compressed"), audioFile))
                .addFormDataPart("transcriptions", "script.txt", RequestBody.create(MediaType.parse("text/plain"), scriptFile))
                .build();


        System.out.println(formBody);


        Request request = new Request.Builder()

                .header("Ocp-Apim-Subscription-Key", subKey)
                .addHeader("Ocp-Apim-Subscription-Key", subKey)
                .addHeader("Content-Type", formBody.contentType().toString())
                .post(formBody)
                .url(Url)
                .build();

        System.out.println("Data upload request : "+ request);
        System.out.println("Data upload request : "+ request.body());
        System.out.println("Data upload request : "+ request.body().toString());
        //Response response = client.newCall(request).execute();
        //System.out.println("data upload response "+response.body().string());
        //response.close();
        Call call = client.newCall(request);
        call.enqueue(new Callback() {
            @Override
            public void onFailure(@NotNull Call call, @NotNull IOException e) {
                e.printStackTrace();
            }

            @Override
            public void onResponse(@NotNull Call call, @NotNull Response response) throws IOException {
                System.out.println("Response "+response);
            }
        });
        return null;
    }

The error is

Response{protocol=http/1.1, code=500, message=Internal Server Error, url=https://koreacentral.customvoice.api.speech.microsoft.com/api/texttospeech/v3.0-beta1//datasets/upload}

The Internal Server Error seems to be wrong, since it works if I send the request through Python, using

from requests_toolbelt.multipart.encoder import MultipartEncoder

Upvotes: 1

Views: 2683

Answers (1)

Qian Sijianhao
Qian Sijianhao

Reputation: 564

Code 500 means the server receives your request but fail to complete it.As the server performs well while using python according to your description, I guess that you got something wrong in your HTTP-Header or multipart/form-data.But it cannot be find out yet by the only info.I suggest that you should compare the data you send through okhttp and python to find out the difference.

Upvotes: 1

Related Questions