呼叫MimeMessage.saveChanges()封闭消息,它将通过将MIME结构级联到您身体部位上的MimeBodyPart.updateHeaders()调用来更新头部。正是这个updateHeaders呼叫将内容类型从DataHandler转移到该部分的MIME Content-Type标题。
当您设置MimeBodyPart的内容,JavaMail的内部(不是很明显)创建一个DataHandler对象包装你传入的对象。该部分的Content-Type头球不立即更新。
由于您没有包含MimeMessage而MimeBodyPart.updateHeaders()不是public,所以在测试程序中没有直接的方法。
这里有一个工作示例照亮预期和意外的输出:
public class MailTest {
public static void main(String[] args) throws Exception {
Session mailSession = Session.getInstance(new Properties());
Transport transport = mailSession.getTransport();
String text = "Hello, World";
String html = "
" + text + "
";MimeMessage message = new MimeMessage(mailSession);
Multipart multipart = new MimeMultipart("alternative");
MimeBodyPart textPart = new MimeBodyPart();
textPart.setText(text, "utf-8");
MimeBodyPart htmlPart = new MimeBodyPart();
htmlPart.setContent(html, "text/html; charset=utf-8");
multipart.addBodyPart(textPart);
multipart.addBodyPart(htmlPart);
message.setContent(multipart);
// Unexpected output.
System.out.println("HTML = text/html : " + htmlPart.isMimeType("text/html"));
System.out.println("HTML Content Type: " + htmlPart.getContentType());
// Required magic (violates principle of least astonishment).
message.saveChanges();
// Output now correct.
System.out.println("TEXT = text/plain: " + textPart.isMimeType("text/plain"));
System.out.println("HTML = text/html : " + htmlPart.isMimeType("text/html"));
System.out.println("HTML Content Type: " + htmlPart.getContentType());
System.out.println("HTML Data Handler: " + htmlPart.getDataHandler().getContentType());
}
}