18

我正在尝试使用 JavaMail 以 html 格式发送电子邮件,但它似乎总是仅在 Outlook 中显示为文本电子邮件。

这是我的代码:

try 
{
    Properties props = System.getProperties();
    props.put("mail.smtp.host", mailserver);
    props.put("mail.smtp.from", fromEmail);
    props.put("mail.smtp.auth", authentication);
    props.put("mail.smtp.port", port);
    Session session = Session.getDefaultInstance(props, null);      

    // -- Create a new message --
    MimeMessage message = new MimeMessage(session);

    // -- Set the FROM and TO fields --
    message.setFrom(new InternetAddress(fromEmail, displayName));
    message.setRecipients(Message.RecipientType.TO, InternetAddress.parse(to, false));

    MimeMultipart content = new MimeMultipart();
    MimeBodyPart text = new MimeBodyPart();
    MimeBodyPart html = new MimeBodyPart();

    text.setText(textBody);
    text.setHeader("MIME-Version" , "1.0" );
    text.setHeader("Content-Type" , text.getContentType() );

    html.setContent(htmlBody, "text/html");
    html.setHeader("MIME-Version" , "1.0" );
    html.setHeader("Content-Type" , html.getContentType() );

    content.addBodyPart(text);
    content.addBodyPart(html);

    message.setContent( content );
    message.setHeader("MIME-Version" , "1.0" );
    message.setHeader("Content-Type" , content.getContentType() );
    message.setHeader("X-Mailer", "My own custom mailer");

    // -- Set the subject --
    message.setSubject(subject);

    // -- Set some other header information --
    message.setSentDate(new Date());

    // INFO: only SMTP protocol is supported for now...
    Transport transport = session.getTransport("smtp");
    transport.connect(mailserver, username, password);
    message.saveChanges();

    // -- Send the message --
    transport.sendMessage(message, message.getAllRecipients());
    transport.close();

    return true;

} catch (Exception e) {
    LOGGER.error(e.getMessage(), e);
    throw e;
}       

任何想法为什么电子邮件的 html 版本不会显示在 Outlook 中?

4

8 回答 8

16

经过大量的调查,我已经能够取得一些重大进展。

首先,我推荐使用Jakarta Commons Email库,而不是直接使用 JavaMail。这确实简化了很多问题!

现在的代码是:

HtmlEmail email = new HtmlEmail();

email.setHostName(mailserver);
email.setAuthentication(username, password);
email.setSmtpPort(port);
email.setFrom(fromEmail);
email.addTo(to);
email.setSubject(subject);

email.setTextMsg(textBody);
email.setHtmlMsg(htmlBody);

email.setDebug(true);

email.send();

讲简单。

但是,仍然存在一个问题。电子邮件的 html 版本在 Gmail、Hotmail 等中运行良好。但它仍然无法在 Outlook 中正确显示。它总是想显示文本版本,我不知道为什么。我怀疑这是 Outlook 中的设置,但我找不到它...

于 2008-11-27T20:33:39.967 回答
5

除了html.setHeader("Content-Type", html.getContentType()) 按照建议删除呼叫之外,我还将替换该行:

MimeMultipart content = new MimeMultipart();

…和:

MimeMultipart content = new MimeMultiPart("alternative");

...并删除该行:

message.setHeader("Content-Type" , content.getContentType() );

默认的 MimeMultiPart 构造函数可能会导致“多部分/混合”内容类型出现问题。

当使用 multipart/alternative 时,替代品按照它们对原件的忠实程度排序,最好的再现在最后。但是,客户端通常会为用户提供显示纯文本的选项,即使存在 HTML 也是如此。您确定 Outlook 中未启用此选项吗?其他用户代理(如 Thunderbird 或 GMail)如何处理您的邮件?

此外,请确保 HTML 格式正确。我会使用W3 验证服务验证 HTML 内容,并可能将其保存到文件中并使用不同版本的 IE 进行查看。也许那里有一个缺陷导致 Outlook 回退到纯文本。

于 2008-11-26T22:42:58.367 回答
3
html.setContent(htmlBody, "text/html");
html.setHeader("MIME-Version" , "1.0" );
html.setHeader("Content-Type" , html.getContentType() );

setContentsetHeader("Content-Type", String)做同样的事情 - 是否有可能html.getContentType()返回其他东西text/html

根据评论和@PhilLho & @erickson 的回答进行扩展(天啊,我必须慢慢打字),使用:

MimeMultipart content = new MimeMultipart("alternative")
于 2008-11-26T22:03:39.693 回答
3

将此更改为:

message.setContent(new String(sBuffer.toString().getBytes(), "iso-8859-1"), "text/html; charset=\"iso-8859-1\"");

内容字符集需要设置,我不明白为什么内容本身。应该是:

message.setContent(sBuffer.toString(), "text/html;charset=iso-8859-1");
于 2010-01-12T15:09:47.233 回答
3

我使用了以下代码:

mimeBodyPart1.setDataHandler(new DataHandler(new ByteArrayDataSource(messageBody, "text/html; charset=utf-8")));
multiPart.addBodyPart(mimeBodyPart1);
message.setContent(multiPart, "text/html; charset=utf-8");

现在,Outlookhtml格式显示。

于 2012-09-20T07:04:00.190 回答
1

您应该查看接收到的消息的来源:消息的 Content-Type 是 multipart/alternative 吗?

于 2008-11-26T22:32:25.470 回答
1
message.setContent(new String(sBuffer.toString().getBytes(), "iso-8859-1"), "text/html; charset=iso-8859-1");

应该解决您的问题(删除\"字符)。

于 2010-09-14T06:08:19.233 回答
0

workaroung 解决方案已解决 Outlook 2003:此消息使用 Internet 服务不支持的字符集。无法正确显示。

这可能是由于编码。大多数 html 页面使用 iso-8859-1 而不是 cp-1252 尝试更改

例如,您的代码是:

message.setContent(sBuffer.toString(), "text/html");

将其更改为:

message.setContent(new String(sBuffer.toString().getBytes(), "iso-8859-1"), "text/html; charset=\"iso-8859-1\"");

这会引发一个新的检查异常:java.io.UnsupportedEncodingException,因此您需要声明它被抛出或捕获。支持 iso-8859-1 因此,除非您的 rt.jar 损坏了某些内容,否则永远不会引发异常。

问候, 贾维德 javeed.mca@gmail.com

于 2009-03-10T15:15:57.473 回答