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

121,894

Solution 1

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

Solution 2

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");

Solution 3

Try with this:

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

Solution 4

What about using:

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

In the documentation of getContentType it says that the value returned is found using getHeader(name). So if you set the header using setHeader I guess everything should be fine.

Solution 5

There is a method setText() which takes 3 arguments :

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

Parameters:

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

NOTE: the subtype takes text after / in MIME types so for ex.

  • text/html would be html
  • text/css would be css
  • and so on..
Share:
121,894
necromancer
Author by

necromancer

Updated on January 23, 2021

Comments

  • necromancer
    necromancer over 3 years

    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