Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to set MimeBodyPart ContentType to "text/html"?

The program below shows an unexpected return value for HTML multipart MIME type. Why does this program print text/plain and not 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());
  }
}

I have tried numerous alternative ways including setting a ByteArrayDataSource wrapped in a DataHandler, but to no avail. The same thing happens when I try this with a MimeMessage instead of a MimeBodyPart.

To compile and run on Linux:

javac -classpath .:activation.jar:mail.jar Main.java
java -classpath .:activation.jar:mail.jar Main
like image 411
necromancer Avatar asked Feb 17 '11 12:02

necromancer


3 Answers

Call MimeMessage.saveChanges() on the enclosing message, which will update the headers by cascading down the MIME structure into a call to MimeBodyPart.updateHeaders() on your body part. It's this updateHeaders call that transfers the content type from the DataHandler to the part's MIME Content-Type header.

When you set the content of a MimeBodyPart, JavaMail internally (and not obviously) creates a DataHandler object wrapping the object you passed in. The part's Content-Type header is not updated immediately.

There's no straightforward way to do it in your test program, since you don't have a containing MimeMessage and MimeBodyPart.updateHeaders() isn't public.


Here's a working example that illuminates expected and unexpected outputs:

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() );
  }
}
like image 146
dkarp Avatar answered Nov 18 '22 19:11

dkarp


Don't know why (the method is not documented), but by looking at the source code, this line should do it :

mime_body_part.setHeader("Content-Type", "text/html");
like image 27
JB Nizet Avatar answered Nov 18 '22 19:11

JB Nizet


Try with this:

msg.setContent(email.getBody(), "text/html; charset=ISO-8859-1");
like image 6
mesrar Avatar answered Nov 18 '22 20:11

mesrar