使用 javamail api 发送的 html 电子邮件正文在 Outlook 中出现乱码

Posted

技术标签:

【中文标题】使用 javamail api 发送的 html 电子邮件正文在 Outlook 中出现乱码【英文标题】:html email body sent using javamail api appears garbled in outlook 【发布时间】:2017-07-21 03:37:34 【问题描述】:

我正在使用以下代码向不同域的多个用户发送邮件。

        String emailBody = "<html>Some html text goes here</html>"
    String from = "from@domain1.com"
    String bcc = "bcc@domain2.com"
    String subject = "Some subject..."
    List attachments = "Some image attachments ..."
    MimeMessage message = new MimeMessage(session);
    message.setHeader("Content-Type", "text/html; charset=UTF-16")
    message.setHeader("Accept-Language", "en-US")
    message.setHeader("Content-Language", "en-US")

    message.setFrom(new InternetAddress(from));
    message.setRecipients(Message.RecipientType.BCC,InternetAddress.parse(bcc));
    message.setSubject(subject);

    // creates message part
    MimeBodyPart messageBodyPart = new MimeBodyPart();
    messageBodyPart.setContent(emailBody, "text/html; charset=UTF-16");

    // creates multi-part
    Multipart multipart = new MimeMultipart();
    multipart.addBodyPart(messageBodyPart);

    addAttachmentsToMultiPart(multipart,attachments)

    message.setContent(multipart);

    Transport.send(message);

电子邮件正文完全是英文。但是很少有域的用户会收到中文字符。当我查看body的html源代码时,我发现它有一部分是乱码。一些原始的 html 文本是完整的,文本之间的一些垃圾字符没有特定的顺序。此邮件经过“Tomcat 应用程序 -> 公司邮件服务器 -> Outlook.office365.com 服务器 -> 目标邮件服务器 -> 最终用户 Outlook 客户端”的路径。

经过一番研究,我发现这个问题可能是由于字符编码造成的。为了测试它,我尝试将此邮件发送到 gamil.com。邮件正文在 gmail 中正确显示,但我注意到在标头部分中找到了以下标头,并且整个正文部分是 base64 编码的。

Content-Type: text/html; charset="UTF-16"
Content-Transfer-Encoding: base64

我不确定“Content-Transfer-Encoding”是如何在标头上设置的,以及邮件正文在哪里进行编码。但我在最终用户邮件属性中没有看到类似的标题。我尝试将“Content-Transfer-Encoding”明确设置为“base64”、“quoted-printable”(和其他类型),但它总是被忽略,gmail 总是将它作为 base64 接收。此设置对最终用户邮件没有影响。他们总是收到相同的垃圾。

谁能帮我理解可能是什么问题以及如何解决它

【问题讨论】:

【参考方案1】:

我们的代码与您编写的非常相似,您可以尝试的唯一区别是:

我们没有在邮件中设置任何标题 我们使用稍微不同的正文内容类型 - text/html; charset=utf-8

顺便说一句,我们使用com.google.common.net.MediaType 将媒体类型传递给电子邮件发送类,因此您可以使用MediaType.toString() 来获取内容类型。

【讨论】:

【参考方案2】:

经过大量的研究和实验,我解决了。基本上有两个问题

    不应在 MimeMessage 级别设置字符集,而应在单个 MimeBodyPart 级别设置。

    将 UTF-16 更改为 UTF-8。某些电子邮件客户端/服务器无法正确处理 UTF-16,或者它们未配置为处理 UTF-16。

【讨论】:

以上是关于使用 javamail api 发送的 html 电子邮件正文在 Outlook 中出现乱码的主要内容,如果未能解决你的问题,请参考以下文章

JavaMail API 发送电子邮件

使用 javamail API 发送带有附件的电子邮件

使用 JavaMail API 时出现 SSLException

Spring JavaMail发送邮件

使用 Javamail API 从 yahoo id 向其他电子邮件 id 发送邮件

Spring JavaMail发送邮件