Как загрузить аудиофайл в формате Apex через MultiPart FormData - PullRequest
1 голос
/ 19 апреля 2019

Я работаю над проектом, в котором мне нужно загрузить аудиофайл во внешний веб-сервис через код Apex. Поэтому я использую данные многоэлементной формы, чтобы делать то же самое, но каждый раз, когда я получаю сообщение об ошибке, т.е. ActionController::UnknownFormat

Я пытаюсь сделать то же самое с помощью составных данных формы в apex.

String body = '--' + boundary + '\r\n';     
body += 'Content-Disposition: form-data; name="recording[s3_location]"; filename="abc.mp3"\r\nContent-Type: audio/mpeg\r\n\r\n';
body += 'F:\Test.mp3\r\n';
body += '--' + boundary + '--';

Expected result code: 201(success)
Actual Result Code:   500(ActionController::UnknownFormat)

Я пытался с почтальоном, он работает нормально, но всякий раз, когда я пытаюсь с моим кодом, я получаю исключение. Пожалуйста, помогите мне. Заранее спасибо:)

1 Ответ

0 голосов
/ 01 мая 2019

Вот рабочее решение для отправки одного файла за раз:

// form boundary must be a string that will very likely never appear again in the form
public static final String BOUNDARY = '----FormBoundary4Amf13kZd';
public static final String EXTRABOUNDARY = '--' + BOUNDARY;

/**
 * 
 *
 * @param file The file that will be uploaded.
 * @param contentType The content-type of the file.  Will default to application/octet-stream.
 * @param filename Name to give the file.
 * @param formDataMap Any extra metadata that you want to send.
 *
 * @return Blob of the complete multipart form.
 */
public static Blob multiPartFormDataBody(Blob file, String contentType, String filename, Map<String, String> metadataMap) {
    contentType = contentType == '' ? 'application/octet-stream' : contentType;
    String bodyStartHex = EncodingUtil.convertToHex(Blob.valueOf(EXTRABOUNDARY + '\r\nContent-Disposition: form-data; name=\"file\"; filename="' + filename + '"\r\nContent-Type: ' + contentType + '\r\n\r\n'));
    String bodyEndHex = EncodingUtil.convertToHex(Blob.valueOf(EXTRABOUNDARY + '--\r\n'));

    bodyStartHex += EncodingUtil.convertToHex(file);
    if (metadataMap != null && metadataMap.size() != 0) {
        String formElements = '\r\n';
        for (String key : metadataMap.keySet()) {
            formElements += EXTRABOUNDARY + '\r\nContent-Disposition: form-data; name=\"' + key + '\"\r\n\r\n' + metadataMap.get(key) + '\r\n';
        }
        bodyStartHex += EncodingUtil.convertToHex(Blob.valueOf(formElements));
    } else {
        // the extra '--' at the end is crucial
        bodyEndHex = EncodingUtil.convertToHex(Blob.valueOf('\r\n' + EXTRABOUNDARY + '--'));
    }
    return EncodingUtil.convertFromHex(bodyStartHex + bodyEndHex);
}

Здесь важно отметить, что вы ДОЛЖНЫ преобразовать всю строку в форме mutltipart в шестнадцатеричную строку, а затем обратно в Blob перед отправкой на внешний веб-сервис, поскольку вы не можете смешивать двоичный файл и граничные строки UTF-8. , Сначала вы получаете блоб границ и метаданные и конвертируете их в гекс. Затем вы берете входной файл Blob и конвертируете его в гекс. Затем вы комбинируете шестнадцатеричные строки вместе и конвертируете их обратно в BLOB-объект для отправки через HttpRequest:

public static HttpResponse sendMultiPartForm(Blob file, String contentType, String filename, Map<String, String> metadataMap) {
    HttpRequest request = new HttpRequest();
    Http http = new Http();
    request.setEndpoint('https://example.com/api/upload');
    request.setMethod('POST');
    // Boundary must be set to exactly what was set before
    request.setHeader('Content-Type', 'multipart/form-data; boundary=' + BOUNDARY);
    request.setBodyAsBlob(multiPartFormDataBody(file, contentType, filename, metadataMap));
    request.setHeader('Content-Length', String.valueOf(request.getBodyAsBlob().size()));
    return http.send(request);
}

Я пропустил объяснения возврата каретки и перевода строки, потому что они должны быть настолько точными, что, честно говоря, каждый должен просто скопировать и вставить их. Чтобы понять все правильно, потребовалось много проб и ошибок.

...