This article provides a step-by-step guide on how to add attachments to an e-mail message to be sent via a SMTP server, using the JavaMail API. To understand how attachments are stored inside an e-mail message, let’s take a look at the following picture:
As we can see, a message comprises of a header and a body. The body must be of type Multipart for containing attachments. The Multipart object holds multiple parts in which each part is represented as a type of BodyPart whose subclass, MimeBodyPart – can take a file as its content.
The steps to create a multipart message with multiple parts are as follows:
Message message = new MimeMessage(session); Multipart multipart = new MimeMultipart();
// creates body part for the message MimeBodyPart messageBodyPart = new MimeBodyPart(); messageBodyPart.setContent(message, "text/html");
// creates body part for the attachment MimeBodyPart attachPart = new MimeBodyPart();
// code to add attachment...will be revealed later
// adds parts to the multipart multipart.addBodyPart(messageBodyPart); multipart.addBodyPart(attachPart);
// sets the multipart as message's content message.setContent(multipart); |
The MimeBodyPart class provides some convenient methods for attaching a file, but the way is different between JavaMail 1.3 and JavaMail 1.4. With JavaMail 1.3, it requires writing the following code to add an attachment:
// JavaMail 1.3 MimeBodyPart attachPart = new MimeBodyPart(); String attachFile = "D:/Documents/MyFile.mp4";
DataSource source = new FileDataSource(attachFile); attachPart.setDataHandler(new DataHandler(source)); attachPart.setFileName(new File(attachFile).getName());
multipart.addBodyPart(attachPart); |
With JavaMail 1.4, adding an attachment is much simpler with the following new methods introduced in the MimeBodyPartclass:
· void attachFile(File file)
· void attachFile(String filePath)
// JavaMail 1.4 MimeBodyPart attachPart = new MimeBodyPart(); String attachFile = "D:/Documents/MyFile.mp4"; attachPart.attachFile(attachFile); multipart.addBodyPart(attachPart); |
The code for JavaMail 1.3 still works in 1.4.
Now for a sample program, the following class, EmailAttachmentSender – implements a static method,sendEmailWithAttachments() – which can be used for sending an e-mail message with some attachments. This method requires the following parameters:
· For SMTP server information: host, port number, user name (e-mail address), and password.
· For e-mail message: recipient e-mail address, subject, and message.
· For attached files: an array of String for file paths.
Here is the code of the class EmailAttachmentSender:
import java.io.IOException; import java.util.Date; import java.util.Properties;
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;
public class EmailAttachmentSender {
public static void sendEmailWithAttachments(String host, String port, final String userName, final String password, String toAddress, String subject, String message, String[] attachFiles) 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(message, "text/html");
// creates multi-part Multipart multipart = new MimeMultipart(); multipart.addBodyPart(messageBodyPart);
// adds attachments if (attachFiles != null && attachFiles.length > 0) { for (String filePath : attachFiles) { MimeBodyPart attachPart = new MimeBodyPart();
try { attachPart.attachFile(filePath); } catch (IOException ex) { ex.printStackTrace(); }
multipart.addBodyPart(attachPart); } }
// sets the multi-part as e-mail's content msg.setContent(multipart);
// sends the e-mail Transport.send(msg);
}
/** * Test sending e-mail with attachments */ public static void main(String[] args) { // SMTP info String host = "smtp.gmail.com"; String port = "587"; String mailFrom = "your-email-address"; String password = "your-email-password";
// message info String mailTo = "your-friend-email"; String subject = "New email with attachments"; String message = "I have some attachments for you.";
// attachments String[] attachFiles = new String[3]; attachFiles[0] = "e:/Test/Picture.png"; attachFiles[1] = "e:/Test/Music.mp3"; attachFiles[2] = "e:/Test/Video.mp4";
try { sendEmailWithAttachments(host, port, mailFrom, password, mailTo, subject, message, attachFiles); System.out.println("Email sent."); } catch (Exception ex) { System.out.println("Could not send email."); ex.printStackTrace(); } } }
|
NOTE: The JavaMail API requires JavaBeans Activation Framework (JAF) which is included in the JDK 6 and JDK 7. So if you are using JDK 5 or earlier version, you must download the JAF and add the activation.jar file to your classpath.
For Swing-based version of the sample program, see this tutorial: Swing application for sending e-mail (with attachments).