如何将MimeBodyPart ContentType设置为“text/html”?

问题描述:

下面的程序显示了HTML多部分MIME类型的意外返回值。为什么这个程序打印“text/plain”而不是“text/html”?如何将MimeBodyPart ContentType设置为“text/html”?

public class Main { 
    public static void main(String[] args) throws javax.mail.MessagingException, java.io.IOException { 
    javax.mail.internet.MimeBodyPart mime_body_part = new javax.mail.internet.MimeBodyPart(); 
    mime_body_part.setContent("<h1>foo</h1>", "text/html"); 
    System.out.println(mime_body_part.getContentType()); 
    } 
} 

我已经尝试了许多其他方法,包括设置包装在DataHandler中的ByteArrayDataSource,但无济于事。当我用MimeMessage而不是MimeBodyPart尝试这个时,会发生同样的情况。

编译和运行在Linux上:

javac -classpath .:activation.jar:mail.jar Main.java 
java -classpath .:activation.jar:mail.jar Main 

呼叫MimeMessage.saveChanges()封闭消息,它将通过将MIME结构级联到您身体部位上的MimeBodyPart.updateHeaders()调用来更新头部。正是这个updateHeaders呼叫将内容类型从DataHandler转移到该部分的MIME Content-Type标题。

当您设置MimeBodyPart的内容,JavaMail的内部(不是很明显)创建一个DataHandler对象包装你传入的对象。该部分的Content-Type头球立即更新。

由于您没有包含MimeMessageMimeBodyPart.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 = "<h1>" + text + "</h1>"; 

    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()); 
    } 
} 
+1

更新 - 这对我的测试程序很好,但在我的真实代码中没有。区别在于真正的代码是获取由邮件系统创建的MimeMessage对象,然后更新一个部分,然后调用MimeMessage.saveChanges()。这仍然没有改变mimetype(尽管在调用.saveChanges()之前内容已经改变了)。解决方案:我从旧的创建了一个新的MimeMessage(old_mime_message)对象,改变了内容和类型,然后调用.saveChanges(),它对我来说工作得很好。 – necromancer 2011-02-18 00:05:50

+1

MimeMessage.saveChanges()是让我们的junit测试通过所需的魔法。 – 2011-04-15 09:37:51

难道不知道为什么(该法未记录),但是通过查看源代码,此行应该这样做:

mime_body_part.setHeader("Content-Type", "text/html"); 
+4

谢谢 - 我很感谢您的帮助。我选择了一个不同的答案,因为它更好地适应了图书馆的使用方式。但你的回答对于我立即完成紧急任务是非常有价值的。再次感谢。 – necromancer 2011-02-17 23:12:12

关于使用什么:

mime_body_part.setHeader("Content-Type", "text/html"); 

在它说,返回的值是找到U中的documentation of getContentType唱getHeader(名字)。所以,如果你使用setHeader设置标题,我想一切都应该没问题。

+1

谢谢 - 我很感谢你的帮助。我选择了一个不同的答案,因为它更好地适应了图书馆的使用方式。但你的回答对于我立即完成紧急任务是非常有价值的。再次感谢。 – necromancer 2011-02-17 23:11:36

试试这个:

msg.setContent(email.getBody(), "text/html; charset=ISO-8859-1"); 

对于我来说,我设置两次:

(MimeBodyPart)messageBodyPart.setContent(content, text/html) 
(Multipart)multipart.addBodyPart(messageBodyPart) 
(MimeMessage)msg.setContent(multipart, text/html) 

和它一直工作正常。

有一种方法setText()包含3个参数:

public void setText(String text, String charset, String subtype) 
    throws MessagingException 

参数:

text - the text content to set 
charset - the charset to use for the text 
subtype - the MIME subtype to use (e.g., "html") 

注:后/亚型采用文本MIME类型所以前。

  • text/html的是HTML
  • 文/ CSS将CSS
  • 等..

使用"<h1>STRING<h1>".getBytes();您可以创建一个ByteArrayDataSource与内容类型和设置setDataHandler在您的MimeBodyPart

尝试:

String html "Test JavaMail API example. <br><br> Regards, <br>Ivonei Jr" 
byte[] bytes = html.getBytes(); 
DataSource dataSourceHtml= new ByteArrayDataSource(bytes, "text/html"); 
MimeBodyPart bodyPart = new MimeBodyPart(); 
bodyPart.setDataHandler(new DataHandler(dataSourceHtml)); 

MimeMultipart mimeMultipart = new MimeMultipart(); 
mimeMultipart.addBodyPart(bodyPart);