'What is the character encoding Postman use to write multipart file data into request

I am writing a Java application to send multipart request with attached files to an API that help me send an email with the attachments to the specified email.

The API was tested with Postman and can send the email properly. The request body was as in the following picture. Please notice that the attached file is assigned by using Postman's Choose Files button.

enter image description here

Inspecting the body of Postman's request, the following is a part of the attached file content I found in the request.

%PDF-1.5
%    
1 0 obj
<</Type/Catalog/Pages 2 0 R/Lang(th-TH) /StructTreeRoot 43 0 R/MarkInfo<</Marked true>>>>
endobj
2 0 obj
<</Type/Pages/Count 5/Kids[ 3 0 R 25 0 R 29 0 R 34 0 R 38 0 R] >>
endobj
3 0 obj
<</Type/Page/Parent 2 0 R/Resources<</Font<</F1 5 0 R/F2 7 0 R/F3 9 0 R/F4 14 0 R/F5 20 0 R/F6 23 0 R>>/XObject<</Image19 19 0 R/Image22 22 0 R>>/ProcSet[/PDF/Text/ImageB/ImageC/ImageI] >>/MediaBox[ 0 0 595.32 841.92] /Contents 4 0 R/Group<</Type/Group/S/Transparency/CS/DeviceRGB>>/Tabs/S/StructParents 0>>
endobj
4 0 obj
<</Filter/FlateDecode/Length 1928>>
stream
x  Y[o9~        R\ /+4R  e v ] x@<  ji
 ]Ŀ s  3{ RV@If  ܾs  e:1 :ˉU zK   * =U ܬ  7O  tB^  O W v    9  W ׯfuM  + % \
 H˓   '\Q     @A    Po. F  ǯ    p q}6S   9y1  _  #   j  K]g     5}| \    _~ < k GŐ<  v9y     =   /_[* e %G !c -  'e  z< z)  @ > P s  gsY}   v}  .e   
 v e5إ  3 j    z `  g`    g  ӫG CB p Hũ-u<   #2     8  8{G* 9 _  E¨    } ˜`N  | jrH5   1 )cL eUԃT sTd t   P  r =  tR@\   )) s )j .2 d   FE- W Q QϳԻ  =   :P  #y u Q#  U?.OR m/ NC }Zx| 0 }
  m  A   0  " * &   >t    ҝʯ y,  o`5 !`R     "0 w ؍ ;ӓ ^           &   ֥   U  

Problem

I am writing a Java application to send a request to the API, like Postman. I manually construct the request body, mimic everything from Postman request. Everything is fine except for the encoding of the attached file. I use org.apache.commons.io.FileUtils.readFileToString(myFile, "UTF-8") to convert my file to String. I tried many encoding such as UTF-8, UNICODE, Cp1252, ISO_8859_1, ... Nothing give me the same request as in Postman. And the attached file the API send to my email is corrupted.

Could you please suggest what is the character encoding used by Postman in this case. And can I hard-code such encoding in my application so that it works for kind of file?

Update, following is the Java code I used to send to request.

class SendMailAdaptorImpl implements SendMailAdaptor {

    private static final String NEW_LINE = "\r\n";
    private static final String PART_DELIMITER = "Eh0oKOHPOSEIJTzFevDxHhPNKhQl7AP6kQL";

    private final String channelId = "...";
    private final String endpoint = "...";
    private final RestTemplate restTemplate = new RestTemplate();

    @Override
    public APIMailResponse sendMail(String from, String to, String templateId, List<String> templateParameters, File attachment) {
        HttpHeaders headers = new HttpHeaders();
        headers.add(HttpHeaders.CONTENT_TYPE, "multipart/form-data; boundary=" + PART_DELIMITER);
        HttpEntity<String> request = new HttpEntity<>(constructMultipartBody(from, to, templateId, constructTemplateParameter(templateParameters), attachment), headers);
        URI uri = UriComponentsBuilder.fromHttpUrl(endpoint)
                .build().encode(Charset.forName("UTF-8")).toUri();

        APIMailResponse response = restTemplate.postForObject(uri, request, APIMailResponse.class);
        return response;
    }

    private String constructMultipartBody(String from, String to, String templateId, String templateParameters, File attachement) {
        StringBuilder builder = new StringBuilder()
                .append("--" + PART_DELIMITER)
                .append(NEW_LINE)
                .append("Content-Disposition: form-data; name=\"to\"")
                .append(NEW_LINE)
                .append(NEW_LINE)
                .append(to)
                .append(NEW_LINE)
                .append("--" + PART_DELIMITER)
                .append(NEW_LINE)
                .append("Content-Disposition: form-data; name=\"from\"")
                .append(NEW_LINE)
                .append(NEW_LINE)
                .append(from)
                .append(NEW_LINE)
                .append("--" + PART_DELIMITER)
                .append(NEW_LINE)
                .append("Content-Disposition: form-data; name=\"template_id\"")
                .append(NEW_LINE)
                .append(NEW_LINE)
                .append(templateId)
                .append(NEW_LINE)
                .append("--" + PART_DELIMITER)
                .append(NEW_LINE)
                .append("Content-Disposition: form-data; name=\"channel_id\"")
                .append(NEW_LINE)
                .append(NEW_LINE)
                .append(this.channelId)
                .append(NEW_LINE)
                .append("--" + PART_DELIMITER)
                .append(NEW_LINE)
                .append("Content-Disposition: form-data; name=\"template_parameter\"")
                .append(NEW_LINE)
                .append(NEW_LINE)
                .append(templateParameters)
                .append(NEW_LINE)
                .append("--" + PART_DELIMITER + "--");

        if (attachement != null) {
            builder.append(NEW_LINE)
                    .append(NEW_LINE)
                    .append("Content-Disposition: form-data; name=\"attach_file_content\"; filename=\"" + attachement.getName() + "\"")
                    .append(NEW_LINE)
                    .append("Content-Type: " + guessAttachmentMimeType(attachement))
                    .append(NEW_LINE)
                    .append(NEW_LINE)
                    .append(convertAttachmentContent(attachement))
                    .append("--" + PART_DELIMITER + "--")
                    .append("Content-Disposition: form-data; name=\"attach_file_name\"")
                    .append(NEW_LINE)
                    .append(NEW_LINE)
                    .append(attachement.getName())
                    .append(NEW_LINE)
                    .append("--" + PART_DELIMITER + "--");
        }

                return builder.toString();
    }

    private String guessAttachmentMimeType(File attachement) {
        try {
            return Files.probeContentType(attachement.toPath());
        } catch (IOException e) {
            throw new UncheckedIOException(e);
        }
    }

    private String convertAttachmentContent(File attachement) {
        try {
            return FileUtils.readFileToString(attachement, StandardCharsets.ISO_8859_1);
        } catch (IOException e) {
            throw new UncheckedIOException(e);
        }
    }

    private String constructTemplateParameter(List<String> templateParameters) {
        return templateParameters.stream().reduce("Name", (a, b) -> a + "|" + b);
    }
}


Solution 1:[1]

I had the same issue when using "UTF-8". The encoded text was different than what postman was sending in request.

I changed encoding to "iso-8859-1" and then encoded text matched exactly with what postman was encoding with.

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1 deepbond