<img src="cid:imageName.png"></img>
09 December 2014
If you are in the need of generating HTML-based e-mails with images, the simple approach is to simply host the image and link to it in the HTML. This will work, but will cause the reciepients (in most e-mail clients) to be prompted as to whether or not they should download and show the image. If you want to avoid this (and therefore the stigma of a perceived security threat), you can include the image as an attachment in the e-mail and reference it using the attachment’s content ID value:
<img src="cid:imageName.png"></img>
When the e-mail client loads the message, it will now resolve the image from the inlined attachments included in the e-mail. This all
sounds great, but how do you get the images in the e-mail? The solution is to combine the
Spring JavaMailSender with the
Spring Resource interface to
load and store the image data in the generated e-mail. The first step is to load the images as Resource
objects, either from the
file system or classpath (in this example, we will use the classpath):
import org.apache.commons.io.IOUtils;
import org.springframework.core.io.ByteArrayResource;
import org.springframework.core.io.InputStreamSource;
...
InputStreamSource imageSource = new ByteArrayResource(IOUtils.toByteArray(getClass().getResourceAsStream("/images/logo.png")))
The code snippet above uses the Apache Commons IO library to convert
the image bytes (read from the classpath via the getResourceAsStream()
method) into a byte array. The byte array is then wrapped
by the Spring ByteArrayResource
, which we will use to create the inline attachment (we could also use the ClassPathResource
). The next
step is to add the image to the MIME message as an attachment:
import javax.mail.internet.MimeMessage;
import org.springframework.mail.javamail.JavaMailSender;
import org.springframework.mail.javamail.JavaMailSenderImpl;
import org.springframework.mail.javamail.MimeMessageHelper;
...
JavaMailSender mailSender = new JavaMailSenderImpl(); // Or use Spring IoC to inject a pre-configured JavaMailSenderImpl
MimeMessage mimeMessage = mailSender.createMimeMessage();
MimeMessageHelper message = new MimeMessageHelper(mimeMessage, true, "UTF-8");
// Add information to the message, such as subject, recipients, etc
message.addInline("logo.png", imageSource);
The addInline()
method of the MimeMessageHelper
reads the byte data from the InputStreamSource
and creates the inline MIME body part to hold the
attachment. It also sets the content ID to the name provided by the first parameter. Now, all that’s left is to reference the image in our HTML body:
message.setText("<img src=\"cid:logo.png\"></img><div>My logo</div>", true);
Now, when the e-mail is viewed in the reciepient’s e-mail client, the image will be displayed from the attachments. Note that this works with most web mail clients, however, you should only attach images that are referenced by the HTML body, otherwise they may show up as actual attachments in the e-mail client.