View RSS Feed

Java Mail

How to send e-mail with Java

Rate this Entry
by , 02-29-2012 at 03:05 PM (12890 Views)
Sending an e-mail is a trivial task in the information world today. Billions of e-mails are sent everyday on the earth. For those who are Java developers, the ability to send e-mail from within a Java program is trivial also. However the standard Java platform does not include any e-mail functionality by default. Instead, developers have to use a separate library for the e-mail things, it is the JavaMail API. This article will guide you on how to write an email utility to send an e-mail out with the JavaMail API. The email’s content can be plain text or HTML, and can have attachments as well, and Gmail SMTP is used for testing.

The JavaMail API

The JavaMail API has been developed for years and the current stable version is 1.4.4. The home page for JavaMail is at:

http://www.oracle.com/technetwork/ja...ail/index.html

The download is bundled in a zip file and about 3MB. It includes library jar files, sample source code and the API documentation. Oracle states that the JavaMail API is working with JDK 1.4+, however it’s better to work with Java 1.6+.

The JavaMail API supports the following standard mail protocols: IMAP, POP3 and SMTP. Since we are only interested in sending e-mail, we will focus on the SMTP because it is the protocol for sending e-mail messages.

The javax.mail package

The JavaMail API introduces two packages javax.mail and com.sun.mail, the former includes the core classes and interfaces for the specification of the API; the latter is the default provider for implementation. So when writing Java code, we usually use the classes and interfaces from the javax.mail package.

The following describes core interfaces and classes:

  • Session.java: this class represents a mail session. A session loads all properties and settings such as the protocol providers and server settings. There are two types of session: shared and unshared. A shared session can be obtained via the static method getDefaultInstance(); An unshared session can be created via the static method getInstance(). The shared session is shared by multiple applications running on the same JVM, while an unshared one is not.

  • Authenticator.java: developer has to subclass this abstract class in order to provide authentication information (typically username and password) and pass an instance to the session object.

  • PasswordAuthentication.java: this class holds data that is used by the Authenticator.

  • Part.java: this is the common base interface for e-mail messages and body parts. An e-mail message can be made up by multiple parts. The JavaMail API provides various implementation classes like Message, MimeMessage, BodyPart…

  • Message.java: This abstract class represents an email message. An e-mail message can be created for sending or when receiving. The MimeMessage class is a subclass of the Message class.

  • Transport.java: This class represents a message transport which sends e-mail messages across the network.

  • javax.mail.internet.InternetAddresss.java: This class represents an Internet e-mail address. It is used to construct an address to which e-mail messages are sent.



SMTP Settings

Sending e-mail requires a valid e-mail account from a SMTP server, such as Gmail. A SMTP server is responsible for sending e-mail, so it is mandatory to define settings for the SMTP server from which we are going to send e-mail. The settings that have to be specified are:

  • mail.smtp.host: host name of the STMP mail server, such as smtp.gmail.com is host name of Gmail’s SMTP server.

  • mail.smtp.port: port number of the SMTP server.

  • mail.smtp.auth: indicates that the session requires authentication or not, this is often set to true.

  • mail.smtp.starttls.enable: specifies whether the TLS encryption is used or not, this is often set to true.

  • mail.user: user name of the e-mail account on the SMTP server.

  • mail.password: password of the account.



The settings are put into a java.util.Properties object which is passed to a Session object. For example:


Java Code: Set properties for SMTP
        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);

SMTP Authentication

As mentioned earlier in the API section, to provide authentication we have to create a class that extends the Authenticator class. Here is the code of the class:

Java Code: Code of SMTPAuthenticator class
    private class SMTPAuthenticator extends javax.mail.Authenticator {
        private String userName;
        private String password;
       
        public SMTPAuthenticator(String userName, String password) {
            this.userName = userName;
            this.password = password;
        }
       
        public PasswordAuthentication getPasswordAuthentication() {
            return new PasswordAuthentication(userName, password);
        }
    }
The class overrides the method getPasswordAuthentication() to provide user name and password for authentication.


Creating a session

There are two ways to obtain an instance of the Session object. The following code obtains the shared session object:

Java Code: Obtain the shared session object
Session session = Session.getDefaultInstance(properties, auth);
And the following code creates a new instance of an unshared Session:

Java Code: Create a new instance of Session class
Session session = Session.getInstance(properties, auth);
Note that in the above code, instances of the Properties class and Authenticator class are passed into the method.


Creating e-mail message

We create a new object of the MimeMessage class for an Internet e-mail message, and set the following properties to the message object:

  • The sender address.
  • The recipient address.
  • The e-mail’s subject.
  • The sent date.



Then we create a MimeBodyPart object for the content of the e-mail’s body, and add this object to the multi-part object of the e-mail.

Following is the code to create an e-mail message:

Java Code: Create a new message
        MimeMessage 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());
       
        MimeBodyPart messageBodyPart = new MimeBodyPart();
        messageBodyPart.setContent(message, "text/html");
       
        Multipart multipart = new MimeMultipart();
        multipart.addBodyPart(messageBodyPart);

Note that the content type of the message is set to “text/html”, that means it is possible to include HTML tags in the message content.


Adding attachments

To attach a file into the e-mail, it requires working with multi-part message. A message is broken into parts: a part for the text content, a part for the first attachment, a part for the second attachment… The following method adds a file as an attachment to the e-mail’s multipart:

Java Code: Add a file as an attachment
    private void addAttachment(Multipart multipart, String filePath) throws MessagingException {
        MimeBodyPart attachPart = new MimeBodyPart();
        DataSource source = new FileDataSource(filePath);
        attachPart.setDataHandler(new DataHandler(source));
        attachPart.setFileName(new File(filePath).getName());

        multipart.addBodyPart(attachPart);       
    }

Writing the email sender utility

Now we write a class that wires all the pieces together. The class has two methods:

  • addAttachment(): Adds an attachment to the e-mail’s multi-part object.
  • sendEmail(): this is the main method of the class, it accepts several parameters such as SMTP server settings, e-mail’s content, the account to send e-mail and the recipient address.



Following is the code of the class, EmailSender.java:

Java Code: Code of EmailSender class
import java.io.File;
import java.util.Date;
import java.util.Properties;

import javax.activation.DataHandler;
import javax.activation.DataSource;
import javax.activation.FileDataSource;
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 is a utility class that sends e-mail messages.
* @author Ha Minh Nam
*
*/
public class EmailSender {
   
    /**
     * Sends an e-mail with attachments.
     * @param host address of the server
     * @param port port number of the server
     * @param userName email address used to send mails
     * @param password password of the email account
     * @param toAddress email address to send
     * @param subject title of the email
     * @param message content of the email
     * @param attachFiles an array of file paths
     * @throws AddressException
     * @throws MessagingException
     */
    public void sendEmail(String host, String port, String userName, String password,
            String toAddress, String subject, String message, String[] attachFiles)
                throws AddressException, MessagingException {
        // sets SMTP 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 SMTPAuthenticator(userName, password);
        Session session = Session.getInstance(properties, auth);
       
        // creates a new e-mail message
        MimeMessage 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) {
                addAttachment(multipart, filePath);
            }
        }
       
        // sets the multi-part as e-mail's content
        msg.setContent(multipart);
       
        // sends the e-mail
        Transport.send(msg);
       
    }
   
    /**
     * Adds a file as an attachment to the email's content
     * @param multipart
     * @param filePath
     * @throws MessagingException
     */
    private void addAttachment(Multipart multipart, String filePath) throws MessagingException {
        MimeBodyPart attachPart = new MimeBodyPart();
        DataSource source = new FileDataSource(filePath);
        attachPart.setDataHandler(new DataHandler(source));
        attachPart.setFileName(new File(filePath).getName());

        multipart.addBodyPart(attachPart);       
    }
   
    /**
     * This class provides authentication information.
     * @author Ha Minh Nam
     *
     */
    private class SMTPAuthenticator extends javax.mail.Authenticator {
        private String userName;
        private String password;
       
        public SMTPAuthenticator(String userName, String password) {
            this.userName = userName;
            this.password = password;
        }
       
        public PasswordAuthentication getPasswordAuthentication() {
            return new PasswordAuthentication(userName, password);
        }
    }   
}

Testing with Gmail

To test the EmailSender class, we create a test class – the TestEmailSender.java class. The SMTP settings are for a Gmail account. Here is the code of the test class:

Java Code: Code of TestEmailSender class
import javax.mail.MessagingException;
import javax.mail.internet.AddressException;

public class TestEmailSender {
    public static void main(String[] args) throws AddressException, MessagingException {
        String host = "smtp.gmail.com";
        String port = "587";
        String mailFrom = "youremail@gmail.com";
        String mailTo = "myfriendemail@gmail.com";
        String password = "yourpassword";
        String subject = "New email";
        String bodyMessage = "<html><b>Hello</b><br/><i>This is an HTML email with an attachment</i></html>";
       
        EmailSender sender = new EmailSender();
        String[] fileAttachment = {"E:/Freelancer/RentACoder/Bids/Forum/questions.txt"};
        sender.sendEmail(host, port, mailFrom, password, mailTo, subject, bodyMessage, fileAttachment);       
    }
}

Conclusion

Sending an e-mail message is simplified with help of the JavaMail API, so any Java applications can take advantages of the API to automate e-mail related tasks. The JavaMail API is stable and is the best choice of Java developers for e-mail processing.

Submit "How to send e-mail with Java" to Facebook Submit "How to send e-mail with Java" to Digg Submit "How to send e-mail with Java" to del.icio.us Submit "How to send e-mail with Java" to StumbleUpon Submit "How to send e-mail with Java" to Google

Tags: java, javamail, mail, send Add / Edit Tags
Categories
Mail API

Comments