5

I am sending mail with MimeMessageHelper in my Spring Boot application.

How can I tell it to encode the filename, which contains the letter à, so that it would display correctly?

Setting the encoding to UTF-8 when constructing MimeMessageHelper does not seem to help. In Gmail, the resulting attachment is displayed as

=?UTF-8?Q?ex-comp_s.=C3=A0_r.l.?= =?UTF-8?Q?-201\";     filename*1=\"7-07-12_=E2=80=95_2017-07-18

4 Answers 4

14

I've solved the the problem with these lines:

  • System.setProperty("mail.mime.splitlongparameters", "false")
  • MimeMessageHelper helper = new MimeMessageHelper(message, true, "UTF-8")
  • MimeUtility.encodeWord(attachmentFilename)

Here is the example code,

System.setProperty("mail.mime.splitlongparameters", "false");
MimeMessage message = sender.createMimeMessage();
MimeMessageHelper helper = new MimeMessageHelper(message, true, "UTF-8");

// Your email content
helper.setFrom("...");
helper.setTo("...");
helper.setSubject("...");
helper.setText("...");

helper.addAttachment(
    MimeUtility.encodeWord(attachmentFilename),
    attachmentContent
);
0
1

Add this line before MimeMessageHelper instantiation:

System.setProperty("mail.mime.splitlongparameters", "false");
0

I had a similar issue with cyrillic filenames for download. The solution is to encode filename (rfc5987):

public static String rfc5987_encode(final String s) throws UnsupportedEncodingException {
        final byte[] s_bytes = s.getBytes("UTF-8");
        final int len = s_bytes.length;
        final StringBuilder sb = new StringBuilder(len << 1);
        final char[] digits = {'0','1','2','3','4','5','6','7','8','9','A','B','C','D','E','F'};
        final byte[] attr_char = {'!','#','$','&','+','-','.','0','1','2','3','4','5','6','7','8','9',           'A','B','C','D','E','F','G','H','I','J','K','L','M','N','O','P','Q','R','S','T','U','V','W','X','Y','Z','^','_','`',                        'a','b','c','d','e','f','g','h','i','j','k','l','m','n','o','p','q','r','s','t','u','v','w','x','y','z','|', '~'};
        for (int i = 0; i < len; ++i) {
            final byte b = s_bytes[i];
            if (Arrays.binarySearch(attr_char, b) >= 0)
                sb.append((char) b);
            else {
                sb.append('%');
                sb.append(digits[0x0f & (b >>> 4)]);
                sb.append(digits[b & 0x0f]);
            }
        }

        return sb.toString();
    }

and use it this way:

private static final String CONTENT_DISP_PREFIX = "attachment; filename=";
private static final String CONTENT_DISP_EXTRA_PREFIX = "attachment; filename*=UTF-8''";
private static final String USER_AGENT_FIREFOX = "Firefox";
...
if (!ua.contains(USER_AGENT_FIREFOX)) {
            response.setHeader(CONTENT_DISP_HEADER, CONTENT_DISP_PREFIX + "\"" + encodedFileName + "\"");
        } else {
            response.setHeader(CONTENT_DISP_HEADER, CONTENT_DISP_EXTRA_PREFIX  + encodedFileName );
        }

I found this solution here: http://outofrange.ru/2016/11/encode-non-ascii-filename-content-disposition/

0

Had the same problem with Japanese file name and the following steps fixed it,

MimeMessageHelper helper = new MimeMessageHelper(mimeMessage,  MimeMessageHelper.MULTIPART_MODE_MIXED_RELATED, "UTF-8");
//IMP steps
System.setProperty("mail.mime.splitlongparameters", "false");
attachedFileName = MimeUtility.encodeText(attachedFileName, "UTF-8", "Q");
//
helper.addAttachment(attachedFileName, attachmentFile);

The Mimeutility.encodetext without the Q option did not work nor did it work without setting the system.setproperty. This tells the mimeutility to encode the string in a quoted-printable - Found something here - https://stackoverflow.com/a/21575089

Not the answer you're looking for? Browse other questions tagged or ask your own question.