JavaMail - How to insert images into email for sending
- Details
- Written by Nam Ha Minh
- Last Updated on 09 July 2019   |   Print Email
In the tutorial Send e-mail with attachment in Java, we discussed how to attach files to an e-mail message using JavaMail. In this article, we will use a similar technique plus some modification in order to embed some images directly into the message. The embedded images are called inline attachments which users see the images right inside the e-mail’s content. That’s different with regular attachments which the users have to download and open them manually.
The message must in HTML format in order to have inline images, so we should set content type of the message as follows:
MimeBodyPart bodyPart = new MimeBodyPart(); bodyPart.setContent(htmlMessage, "text/html");
Where htmlMessage is a String represents content of the message with HTML tags:
String htmlMessage = "<html>Hi there,<br>"; htmlMessage += "See this cool pic: <img src=\"cid:AbcXyz123\" />"; htmlMessage += "</html>";
As you notice in the HTML code above, we use the <img> tag to include an image, but its src attribute does not point to name of the image. Instead, the src attribute must refer to Content-ID header’s value of a MIME part which contains the actual image, in the following form:
src=”cid:<content_id>”
Then the image part should be created as follows:
MimeBodyPart imagePart = new MimeBodyPart(); imagePart.setHeader("Content-ID", "AbcXyz123"); imagePart.setDisposition(MimeBodyPart.INLINE); // attach the image file imagePart.attachFile(imageFilePath);
The value of the Content-ID header must be a unique identifier. This convention is described in the RFC 2387.
Now let’s create a real example with a utility class and a test program.
1. Coding An Email Utility class
We create an out-of-the-box utility class as follows:
package net.codejava.mail; import java.io.IOException; import java.util.Date; import java.util.Map; import java.util.Properties; import java.util.Set; import javax.mail.Authenticator; import javax.mail.Message; import javax.mail.MessagingException; import javax.mail.Multipart; import javax.mail.PasswordAuthentication; import javax.mail.Session; import javax.mail.Transport; import javax.mail.internet.AddressException; import javax.mail.internet.InternetAddress; import javax.mail.internet.MimeBodyPart; import javax.mail.internet.MimeMessage; import javax.mail.internet.MimeMultipart; /** * This utility class provides a functionality to send an HTML e-mail message * with embedded images. * @author www.codejava.net * */ public class EmbeddedImageEmailUtil { /** * Sends an HTML e-mail with inline images. * @param host SMTP host * @param port SMTP port * @param userName e-mail address of the sender's account * @param password password of the sender's account * @param toAddress e-mail address of the recipient * @param subject e-mail subject * @param htmlBody e-mail content with HTML tags * @param mapInlineImages * key: Content-ID * value: path of the image file * @throws AddressException * @throws MessagingException */ public static void send(String host, String port, final String userName, final String password, String toAddress, String subject, String htmlBody, Map<String, String> mapInlineImages) throws AddressException, MessagingException { // sets SMTP server properties Properties properties = new Properties(); properties.put("mail.smtp.host", host); properties.put("mail.smtp.port", port); properties.put("mail.smtp.auth", "true"); properties.put("mail.smtp.starttls.enable", "true"); properties.put("mail.user", userName); properties.put("mail.password", password); // creates a new session with an authenticator Authenticator auth = new Authenticator() { public PasswordAuthentication getPasswordAuthentication() { return new PasswordAuthentication(userName, password); } }; Session session = Session.getInstance(properties, auth); // creates a new e-mail message Message msg = new MimeMessage(session); msg.setFrom(new InternetAddress(userName)); InternetAddress[] toAddresses = { new InternetAddress(toAddress) }; msg.setRecipients(Message.RecipientType.TO, toAddresses); msg.setSubject(subject); msg.setSentDate(new Date()); // creates message part MimeBodyPart messageBodyPart = new MimeBodyPart(); messageBodyPart.setContent(htmlBody, "text/html"); // creates multi-part Multipart multipart = new MimeMultipart(); multipart.addBodyPart(messageBodyPart); // adds inline image attachments if (mapInlineImages != null && mapInlineImages.size() > 0) { Set<String> setImageID = mapInlineImages.keySet(); for (String contentId : setImageID) { MimeBodyPart imagePart = new MimeBodyPart(); imagePart.setHeader("Content-ID", "<" + contentId + ">"); imagePart.setDisposition(MimeBodyPart.INLINE); String imageFilePath = mapInlineImages.get(contentId); try { imagePart.attachFile(imageFilePath); } catch (IOException ex) { ex.printStackTrace(); } multipart.addBodyPart(imagePart); } } msg.setContent(multipart); Transport.send(msg); } }
Clients can call the static method send() to send an e-mail message in HTML format with embedded images passed via the parameter mapInlineImages. So it’s convenient for embedding an image as follows:
Map<String, String> inlineImages = new HashMap<String, String>(); inlineImages.put("ID123456", "D:/Images/stockchart.jpg");
Note this line:
imagePart.setHeader("Content-ID", "<" + contentId + ">");
The reason that we have to wrap the contentIdbetween the “<” and “>” is because some e-mail clients (such as Gmail) won’t show the inline images without those angle brackets.
2. Coding A Test program for embedding images into emails
Code the test program as follows:
package net.codejava.mail; import java.util.HashMap; import java.util.Map; /** * This program tests out the EmbeddedImageEmailUtil utility class. * @author www.codejava.net * */ public class InlineImageEmailTester { /** * main entry of the program */ public static void main(String[] args) { // SMTP info String host = "smtp.gmail.com"; String port = "587"; String mailFrom = "YOUR_EMAIL"; String password = "YOUR_PASSWORD"; // message info String mailTo = "YOUR_RECIPIENT"; String subject = "Test e-mail with inline images"; StringBuffer body = new StringBuffer("<html>This message contains two inline images.<br>"); body.append("The first image is a chart:<br>"); body.append("<img src=\"cid:image1\" width=\"30%\" height=\"30%\" /><br>"); body.append("The second one is a cube:<br>"); body.append("<img src=\"cid:image2\" width=\"15%\" height=\"15%\" /><br>"); body.append("End of message."); body.append("</html>"); // inline images Map<String, String> inlineImages = new HashMap<String, String>(); inlineImages.put("image1", "E:/Test/chart.png"); inlineImages.put("image2", "E:/Test/cube.jpg"); try { EmbeddedImageEmailUtil.send(host, port, mailFrom, password, mailTo, subject, body.toString(), inlineImages); System.out.println("Email sent."); } catch (Exception ex) { System.out.println("Could not send email."); ex.printStackTrace(); } } }
In this test program, we configure SMTP settings for a GMail account and compose an HTML message with two inline images image1 and image2 which correspond to two actual images file chart.png and cube.jpg.
When running this program, we got the following result in GMail:
And in Microsoft Outlook:
NOTES:
You need to use JavaMail jar files. If you use Maven, add the following dependency to the pom.xml file:
<dependency> <groupId>com.sun.mail</groupId> <artifactId>javax.mail</artifactId> <version>1.6.2</version> </dependency>
This will add the javax.mail-VERSION.jar and activation-VERSION.jar to the project's classpath. If you have to add them manually, download from JavaMail Project page.
Other JavaMail Tutorials:
- How to send plain text email using JavaMail
- How to send email in HTML format using JavaMail
- How to send email with attachments using JavaMail
- How to receive emails from server using JavaMail
- How to search email messages using JavaMail
- How to delete emails programmatically using JavaMail
- How to download attachments in emails using JavaMail
Comments
String htmlMessage = "Hi there,";
htmlMessage += "See this cool pic: ";
htmlMessage += "";
Correct code
String htmlMessage = "Hi there,";
htmlMessage += "See this cool pic: ";
htmlMessage += "";