Setting Content-Type for MimeMessage?

M Sach picture M Sach · Oct 30, 2012 · Viewed 19.3k times · Source

I have one confusion about content type of mime message. Say I have a mime message. It is a multipart message and the body parts are like this

  1. Mime body part containing plain text, html text(like some letters in bold in body)
  2. Second mime body part containing an attachment,
  3. Third mime body part containing one inline image (which is being referred from body with cid)

When I am creating the body part, should I explicitly set the content type for top mime message and then each body part?

If yes, what should they be in the above example?

multipart/alternative is suggested for html, multipart/mixed is suggested for attachments, multipart/related is suggested for inline. I am using all of them, so what should be content-Type for complete message and different body parts?

Just for information I tried to replicate above scenario where I did not set the content type neither for the overall MimeMessage nor for body parts.

But still I get the expected stuff like plain text, Bold letters in body, attachment, inline image on james at right place

How come James is interpreting the mime message and body parts without setting the content type, and how come it is displaying them in right fashion?

Code For Reference

  MimeMessage   msg = new MimeMessage(mailSession);
  MimeMultipart mpart = new MimeMultipart();
  MimeBodyPart bp = new MimeBodyPart();
  bp.setText("plain text and html text like<b>Test</>", CHARSET_UTF_8, MESSAGE_HTML_CONTENT_TYPE);
  // add message body
  mpart.addBodyPart(bp);

 // adding attachment
  MimeBodyPart bodyPart = new MimeBodyPart();
  bodyPart.setFileName("WordFile1");
  file = new File("word file");
  DataSource source = new FileDataSource(file);
  bodyPart.setDataHandler(new DataHandler(source));
  mpart.addBodyPart(bodyPart);


 // adding image inline
  MimeBodyPart bodyPart2 = new MimeBodyPart();
  bodyPart2.setFileName("inline image");
  file2 = new File("image1");
  DataSource source2 = new FileDataSource(file);
  bodyPart2.setDataHandler(new DataHandler(source));
  bodyPart2.setDisposition(MimeBodyPart.INLINE);
  bodyPart2.setHeader("Content-ID", "Unique-CntentId");
  bodyPart2.setHeader("Content-Type", "image/jpeg");
  mpart.addBodyPart(bodyPart2);

  // At last setting multipart In MimeMessage
  msg.setContent(mpart);

With the above code, I get the correct html text, plain text, inline image and attachments at right place in ThunderBird integrated with James.

So I don't understand when and where to set multipart/mixed, multipart/alternative, multipart/related as Content-Type or does the mail server internally set it?

Answer

Bill Shannon picture Bill Shannon · Oct 30, 2012

If I understand what you're trying to do, you want a message with this structure:

  multipart/mixed
    multipart/alternative
      text/plain - a plain text version of the main message body
      multipart/related
        text/html - the html version of the main message body
        image/jpeg - an image referenced by the main body
    application/octet-stream (or whatever) - the attachment

That means three nested multipart pieces. You'll need to specify the subtype for each multipart piece other than the default "mixed".

The multipart/mixed and multipart/alternative pieces are relatively straightforward. The multipart/related piece is more complicated and you might want to read RFC 2387 and/or find some other tutorials to help you with that.

You can simplify the structure by getting rid of the multipart/related and just having the html text reference an image somewhere on the internet.

You should also test that a message with this structure is going to be displayed properly by all the mail readers you care about. Some mail readers will do a better job than others with a complicated structure such as this.