Java Mail API: Sending emails

1. SENDING EMAILS

The Simple Mail T ransfer Protocol (SMTP) is an application layer protocol in the TCP/IP protocol suite which is used to send electronic mails (email). It uses TCP as its underlying transport layer protocol. The SMTP protocol specifies a set of commands and responses to send emails. A sample set of SMTP commands and responses to send an email is shown in Figure 15.1:

In this section, we shall discuss how to send an email containing simple text message. There are three steps to follow to send an email using JavaMail API:

  • Create a Session object that stores necessary information such as host name, user name and password to send an email.
  • Compose a message.
  • Send the message.

1.1. Creating a Session Object

The mail handling (i.e. sending and retrieving) task is typically started by obtaining a javax. maii.Session object. This final Session class represents a mail session. A new Session object may be created or an existing one may be used. To get a Session object, two static methods

getDefaultInstance() and getInstance() are available on Session class.

The former method returns an existing (or a new instance if the method is called for the first time) Session object and later creates a fresh one. Since, the default session is potentially available to all code executing in the same Java virtual machine, an application may prefer to create a new instance for its own using getInstance() method. It has two overloaded versions:

static Session getInstance(Properties props)

static Session getInstance(Properties props, Authenticator authenticator)

The Properties object is used to configure the session. Configuring a session means specifying email host, port number being used etc. The Authenticator object is required if the mail host enforces a user to be authenticated (e.g. providing user name and password).

We know that SMTP itself does not mandate authentication. In practice, there exists some (wrongly configured) mail servers which implements this raw SMTP and hence do not require authentication. However, a good mail server does not open SMTP port (25) directly. Instead, an additional security layer (such as SSL, TSL) is inserted in front of SMTP. Any program that wants to reach the SMTP port, has to pass through this security layer. This security layer takes care of the authentication and finally forwards the request to the SMTP.

Most of the mail servers (such as Gmail, Yahoo) have been configured this way. For these mail servers, we should use the second overloaded version of getinstance () that requires an Authenticator object. We shall discuss sending mails using mail servers that require authentication in detail later in this chapter.

In our first program, we shall use a mail server (webmaii.jusi.ac.in) that does not require authentication. So, we shall use the first version of getinstance() method. Note that mail servers that do not require authentication are potentially vulnerable for external attack and should always be avoided.

Since, the above mentioned methods take a Properties object, let us first create a Properties object as follows:

Properties props = new Properties();

This Properties object is used to configure the Session object. However, this object does not so far contain any property. So, we must set some necessary properties as follows:

String host = “webmaii.jusi.ac.in”;

props.setPropertyC’mail.smtp.host”, host);

This indicates that the mail server webmail.jusl.ac.in is to be used for sending mails. You should use IP address or name of the mail server, where you have an account, in place of webmail. jusl.ac.in.

Alternatively, an existing Properties object may also be used as follows:

Properties props = System.getProperties();

The System.getProperties() method returns the current set of system properties (such as java. version, java.home etc.) as a Properties object. This object is useful if an application wants to use default system properties. However, always make sure that some necessary properties (such as mail. smtp.host) are set properly. The set of required properties is determined by the actual procedure used to send the mail.

The Session object can be created with this property object as follows:

Session session = Session.getInstance(props);

Now, this Session object has relevant information necessary to Transport emails as well as to have access to email Store. Let us now compose a message for delivery.

1.2. Compose a Message

The abstract class javax.mail.Message encapsulates an email message. Since, it is an abstract class, its direct known subclass javax.mail.internet.MimeMessage is usually used to create a mail message as follows:

MimeMessage msg = new MimeMessage(session);

The constructor takes a Session object and creates an empty message. When this message is sent, the session object is consulted for information necessary for email delivery. To populate this message, a number of methods are available on MimeMessage class. For example, setSubject() method sets the subject, and the setText() method sets the (plaintext) body content of the message. The following is an example that fills the message:

String from = “u_roy@it.jusl.ac.in”, to = from;

msg.setFrom(from);

msg.addRecipients(Message.RecipientType.TO, to);

msg.setSubject(“A test mail”);

msg.setText(“Sent a mail without authentication”);

The addRecipients() method adds an email address to the list of intended receiver’s email addresses. The first argument indicates the type of recipients and has possible values Message. RecipientType.TO, Message.RecipientType.CC and Message.RecipientType.BCC. They represent primary (to), Carbon Copy (cc) and Blind Carbon Copy (bcc) recipients respectively.

It has another overloaded version that may be used to specify multiple email addresses:

void addRecipients(Message.RecipientType type, Address[] addresses)

Here, the second argument is a list of recipient’s email addresses.

1.3. Sending the Mail

Sending the mail is as simple as follows:

Transport.send(msg);

The static send() method of Transport class delivers the specified message to all recipient’s addresses, which were added to the message using addRecipients() method. If send() method encounters any of the recipient addresses as invalid (e.g. wrong format or non-existing address), during delivery of message, a SendFailedException is thrown.

Note that success does not always imply that the message is really delivered to the ultimate recipient. The failures may occur in later stages of delivery, where usually an undeliverable message is sent back to the user.

Alternatively, we can send mail using a specific instance from the session for SMTP protocol as follows:

Transport transport = session.getTransport(”smtp”);

transport.connect(host, null, null);

transport.sendMessage(msg, msg.getAllRecipients());

transport.close();

The connect() method, establishes a connection to the specified host and username and password (null if unnecessary). Finally, the sendMessage() delivers the message. Since, connect() method keeps the connection with the mail server active between messages, this method is useful if sending multiple messages is required. The static send() method makes a separate connection to the server for each method call.

The complete source code (SendEmail.java) is given below:

//SendEmail.java

import java.util.*;

import javax.mail.*;

import javax.mail.internet.*;

public class SendEmail {

public static void main(String [] args) {

String host = ”webmail.jusl.ac.in”;

String from = ”u_roy@it.jusl.ac.in”, to = from;

Properties props = new Properties();

props.setProperty(”mail.smtp.host”, host);

Session session = Session.getInstance(props); try{

MimeMessage msg = new MimeMessage(session);

msg.setFrom(from);

msg.addRecipients(Message.RecipientType.TO, to);

msg.setSubject(”A test mail”);

msg.setText(”Sent a mail without authentication”);

Transport.send(msg);

System.out.println(”Sent message successfully….”);

}catch (Exception e) {

e.printStackTrace();

}

}

}

1.4. Compiling and Running the Program

We assume that all the programs in the chapter are developed in a directory: E:\Net\maii. Place the jar file javax.maii.jar in this directory. Go to the E:\Net\maii directory and use the following command to compile our sendEmaii.java:

javac -cp javax.maii.jar;. SendEmaii.java

It generates a single class file sendEmaii.ciass. To execute the program, use the following command:

java -cp javax.maii.jar;. SendEmaii

To show that the mail has really been sent, a snapshot from the mail server interface is shown in Figure 15.2:

2. SENDING EMAILS DIRECTLY USING SOCKET

We know that SMTP itself does not mandate any user authorization procedure. This suggests to us to establish a simple TCP socket to the server that implements the basic SMTP and gives commands to send emails. The email server (webmaii.jusi.ac.in) we have used in our previous program is one such server. The following program sends an email from u_roy@it.jusi.ac.in to itself using the basic socket mechanism.

import java.io.*; import java.net.*; class MailClient {

public static void main(String argv[]) throws Exception {

int port = Integer.parseInt(argv[1]);

BufferedReader inFromUser =

new BufferedReader(new InputStreamReader(System.in));

Socket clientSocket = new Socket(argv[0], port);

if(clientSocket == null) System.out.println(“error”); else {

System.out.println(“connected to the server ” + argv[0] + ” at port ” + port);

DataOutputStream outToServer =

new DataOutputStream(clientSocket.getOutputStream());

BufferedReader inFromServer =

new BufferedReader(new InputStreamReader(clientSocket.getInputStream()));

String[] out = { “HELO : thinkpad\n”,

“mail from: <u_roy@it.jusl.ac.in>\n”,

“rcpt to: <u_roy@it.jusl.ac.in>\n”,

“data\n”,

“This is a sample mail\n.\n”,

“quit\n”

};

try {

System.out.println(“From server: ” + inFromServer.readLine());

for(int i = 0; i < out.length; i++) {

outToServer.writeBytes(out[i]);

System.out.print(“To server: ” + out[i]);

System.out.println(“From server: ” + inFromServer.readLine());

}

}catch(Exception e) {clientSocket.close();}

}

}

}

Compile the program as follows:

javac MailClient.java

Note that it does not use JavaMail API and hence does not require javax .maii.jar file. It creates a socket connection to the port 25 (SMTP port) and fires SMTP commands. Run the program as follows:

java MailClient webmail.jusl.ac.in 25

A sample output for this program is shown in Figure 15.3:

Source: Uttam Kumar Roy (2015), Advanced Java programming, Oxford University Press.

Leave a Reply

Your email address will not be published. Required fields are marked *