Sunday, April 18, 2010

Sending HTML email with images with JavaMail API

In this post, I will build on the previous post about sending attachments with JavaMail. We will send HTML-formatted email with images that we include as attachments with the email. The protocol also allows to link to images on a webserver, but because spammers use this method to validate working email addresses, most email clients block external images.

The main idea is to include images as attachments like we did before, but now we also include a content-id per image we attach. Use HTML-code to format our email and use the cid: prefix along with the content-id in the src-attribute of the img-tag to refer to the image attachment.

The example code:

// Create new message with mail session.
Message message = new MimeMessage(session);

// Create multipart message.
MimeMultipart multipart = new MimeMultipart();

// Create bodypart.
BodyPart bodyPart = new MimeBodyPart();

// Create the HTML with link to image CID.
// Prefix the link with "cid:".
String str = "<html><h1>Hello</h1>" +
"<img src=\"cid:image_cid\"></html>";

// Set the MIME-type to HTML.
bodyPart.setContent(str, "text/html");

// Add the HTML bodypart to the multipart.
multipart.addBodyPart(bodyPart);

// Create another bodypart to include the image attachment.
bodyPart = new MimeBodyPart();

// Read image from file system.
DataSource ds = new FileDataSource("C:\\images\\image.png");
bodyPart.setDataHandler(new DataHandler(ds));

// Set the content-ID of the image attachment.
// Enclose the image CID with the lesser and greater signs.
bodyPart.setHeader("Content-ID", "<image_cid>");

// Add image attachment to multipart.
multipart.addBodyPart(bodyPart);

// Add multipart content to message.
message.setContent(multipart);

// Now set the header and send the email.
...

20 comments:

  1. Hi,

    Is there a way to attach a html file which contains images and receive it as it is instead of embedding the html in mail?

    for example a html page with company logo and just click the attachment to view the html?

    Thanks
    Yacoob

    ReplyDelete
  2. Attach the HTML-file as a normal attachment and use the CID's in links to refer to other image attachments. I think this should work.

    ReplyDelete
  3. Hi,

    Thanks for the immediate response. I tried that it didn't work. Find the code below. Its a well formed html, just placed the img src line

    hello.html:

    img src="cid:logo.gif"

    The java code:

    String host = "host";
    String from = "from-address";
    String to = "to-address";
    String filename = "logo.gif";
    String file1 = "hello.html";

    String msgText1 = "Sending a file.\n";
    String subject = "Sending a file";

    // create some properties and get the default Session
    Properties props = System.getProperties();
    props.put("mail.smtp.host", host);
    Session session = Session.getInstance(props, null);

    try {
    // create a message
    MimeMessage msg = new MimeMessage(session);
    msg.setFrom(new InternetAddress(from));
    InternetAddress[] address = {new InternetAddress(to)};
    msg.setRecipients(Message.RecipientType.TO, address);
    msg.setSubject(subject);

    // create and fill the first message part
    MimeBodyPart mbp1 = new MimeBodyPart();
    mbp1.setText(msgText1);
    mbp1.attachFile(file1);

    // create the second message part
    MimeBodyPart mbp2 = new MimeBodyPart();

    // attach the file to the message
    mbp2.attachFile(filename);

    // create the Multipart and add its parts to it
    Multipart mp = new MimeMultipart();
    mp.addBodyPart(mbp1);
    mp.addBodyPart(mbp2);

    // add the Multipart to the message
    msg.setContent(mp);

    // set the Date: header
    msg.setSentDate(new Date());

    // send the message
    Transport.send(msg);

    } catch (MessagingException mex) {
    mex.printStackTrace();
    Exception ex = null;
    if ((ex = mex.getNextException()) != null) {
    ex.printStackTrace();
    }
    } catch (IOException ioex) {
    ioex.printStackTrace();
    }
    }

    Your help is hightly appreciated

    Thanks,
    Yacoob

    ReplyDelete
  4. On second thoughts, this might not work. If you click on the attachment in your email client. Most of the time two options are presented to you: "Save as ..." and "Open". In the first case, the HTML file is downloaded to a location you specified. In the second case, the file is downloaded to a temporary location on you hard drive. In both cases, the links to the images are broken. The images are not saved to your hard drive, and if they are, the CID links will probably not work.

    I haven't tested this yet, but it sounds logical do you agree?

    ReplyDelete
  5. Yes i perfectly agree with you. But from a business user perspective, he would still want to see the proper html.

    Thanks for your input

    ReplyDelete
  6. Hi,

    I want your help. Currently I am working on my University Project. I am making A E-marking project using JEE MVC (JSP + Servlet)and Glass Fish. I have required Servlet + JSP code for sending Email.
    Above mentioned Code is useful, but I am confused.

    ReplyDelete
  7. Sir, I am using Netbeans 6.9.1

    ReplyDelete
  8. What do you mean by "you're confused"? Are you having problems with the code?

    ReplyDelete
  9. Actually I am new in in this field and have no experience.
    I want make E-mail form in JSP and its control in Servlet controller. Moreover I want also make different E-mail templates and E-mail address should retrieved in data base.

    For this, what should I do.

    ReplyDelete
  10. Well, what I would do is (in this order):
    1. Create a JSP form
    2. Create the form handling code as a Servlet. The email address is loaded from a Property file. A database is not needed, unless you have a lot of email addresses.
    3. Create a class for the actual sending of the email. The email session is configured in Glassfish.

    This blogpost will help you out: http://javaeenotes.blogspot.com/2010/04/using-javamail-api-with-glassfish-and.html

    ReplyDelete
  11. Thanks.
    I am now able to send Text and html mail with using JSP Form and java class. But I am in trouble to send html email with picture.

    Can you guide me to send html email with picture and Email tracking, bounce rate and clicking count.
    actually I want to make email and SMS base email marketing project.

    ReplyDelete
  12. Attaching images with email is explained in this blogpost. What kind of troubles are you running into?

    ReplyDelete
  13. what is picture source. I am using Netbeans.

    When I try your code, its give error of no image.

    Further you used image uploading code in java class, I am trying to upload picture in jsp form and pasting html code in message part of jsp.

    Please also guide about email tracking.

    ReplyDelete
  14. Can i add multiple images to it ?
    How ?

    ReplyDelete
    Replies
    1. I am also trying to add multiple images but i am not able to do...if you got the answer can you help me

      Delete
  15. Hi, do you know how to preview/display an HTML file in java EE program? Thanks.

    For example, you need to preview EDM on your browser(which is just a html file imported locally)

    ReplyDelete
  16. Hi ALl,

    I am stuck with my .eml file operation.

    Requirements:

    I have an .eml file containing images and texts, I need to read those and send as it is in .eml file to another reciepients.
    I am able to read send texts but when it comes to image it printing it as empty box.
    Image should not be attached.

    Please help me out, I need code for image operation.

    Below are the materials you may need to investigate:

    1)this is explaination of image in my .eml file.
    Content-Type: image/jpeg
    Content-ID: <_2_0901E8340901E5E0006786BB85257AB7>
    Content-Transfer-Encoding: base64
    and along with this there is encoded values also.

    2) I need to read image and send it as it is to another person.
    Note: I dont have image src lodation as i m already taking it.


    please look into this:

    Thanks,
    Deepak kumar
    India-+91-7829296000

    ReplyDelete
  17. Hi,

    Just saw your question. What is your requirement, is it reading the eml file and sending it as is? If so can't we get the multipart and send it? something like

    MimeMultipart multipart = (MimeMultipart)message.getContent();

    and set this multipart in your mail.

    If you still have queries, could you attach your eml file and your code.

    -Yacoob

    ReplyDelete
  18. Hi,
    I used same code.it works fine in outlook means images come as inline how ever while checking same mail in browser inline image not seen and there is ATT00001.bin file coming as attachment.

    can you please help related to this ?

    Thanks,
    Sudhir

    ReplyDelete
  19. can i place one image over another in email as embedded,if possible please let me ho i can do it.

    ReplyDelete