Best Practices - Sending javamail mime multipart emails - and gmail

PrecisionPete picture PrecisionPete · Feb 7, 2013 · Viewed 47.9k times · Source

I have a Tomcat application that needs to send confirmation emails etc. I have coded the emailer with Javamail (mail.jar) to send multipart text/html emails. I based the code on the Java EE examples. I'm using the SMTP MTA on the local server.

It works great. In Outlook, I see the HTML version. If I drag it into the Outlook spam folder, I see the text version. So I interpret that as saying it works.

However, if I view the emails in Gmail, I see only the text version. I know the HTML is there (that's where Outlook got it from). But Gmail is not showing it... I have lots of emails from other systems that show as HTML in Gmail.

Can anyone point me to the spec that shows what I am missing? Are there special headers I need to create?

Thanks

Code looks like this:

Message message = new MimeMessage(session);
Multipart multiPart = new MimeMultipart("alternative");

try {

    MimeBodyPart textPart = new MimeBodyPart();
    textPart.setText(text, "utf-8");

    MimeBodyPart htmlPart = new MimeBodyPart();
    htmlPart.setContent(html, "text/html; charset=utf-8");

    multiPart.addBodyPart(htmlPart);
    multiPart.addBodyPart(textPart);
    message.setContent(multiPart);

    if(from != null){
        message.setFrom(new InternetAddress(from));
    }else
        message.setFrom();

    if(replyto != null)
        message.setReplyTo(new InternetAddress[]{new InternetAddress(replyto)});
    else
        message.setReplyTo(new InternetAddress[]{new InternetAddress(from)});

    InternetAddress[] toAddresses = { new InternetAddress(to) };
    message.setRecipients(Message.RecipientType.TO, toAddresses);
    message.setSubject(subject);
    message.setSentDate(new Date());

    Transport.send(message);

} catch (AddressException e) {
    e.printStackTrace();
    System.out.println("Error: "+e.getMessage());

} catch (MessagingException e) {
    e.printStackTrace();
    System.out.println("Error: "+e.getMessage());

} finally {     
    System.out.println("Email sent!");
}

Answer

PrecisionPete picture PrecisionPete · Feb 17, 2013

Solved! It seems according to the multipart MIME spec, the order of the parts are important. They should be added in order from low fidelity to high fidelity. So it seems GMail follows the spec and uses the last part. In my case I had them HTML, Text. I just swapped the order to Text, HTML and Gmail renders it correctly...

i.e.

MimeBodyPart textPart = new MimeBodyPart();
textPart.setText(text, "utf-8");

MimeBodyPart htmlPart = new MimeBodyPart();
htmlPart.setContent(html, "text/html; charset=utf-8");

multiPart.addBodyPart(textPart); // <-- first
multiPart.addBodyPart(htmlPart); // <-- second
message.setContent(multiPart);

Thanks for the help!