Learning the JavaMail API

The JavaMail API consists of some interfaces and classes used to send, read, and delete e-mail messages. The javax.mail and javax.mail.internet packages contain all the JavaMail core classes. The javax.mail.activation package represents the JavaBean Activation Framework.

Exploring the Core Classes

The JavaMail core classes, which belong to the javax.mail package, are Session, Message, Address, Authenticator, Transport, Store, and Folder. Table 20.1 gives a brief description of each core class.

Table 20.1. Summary of JavaMail Core Classes
ClassDescription
SessionThe key class of the API. A multithreaded object represents the connection factory.
MessageAn abstract class that models an e-mail message. Subclasses provide the actual implementations.
AddressAn abstract class that models the addresses (from and to addresses) in a message. Subclasses provide the specific implementations.
AuthenticatorAn abstract class used to protect mail resources on the mail server.
TransportAn abstract class that models a message transport mechanism for sending an e-mail message.
StoreAn abstract class that models a message store and its access protocol, for storing and retrieving messages. A Store is divided into Folders.
FolderAn abstract class that represents a folder of mail messages. It can contain subfolders.

In the following sections, you'll learn these core classes in more detail. After that, you'll learn how to use those classes to perform e-mail system agent functionality, such as sending, reading, and deleting messages.

Session

The Session class is the primary class of the JavaMail API. It defines a basic mail session. The Session object acts as the connection factory for the JavaMail API, which handles both configuration setting and authentication. It is through the Session object that everything else works. To create a Session object, you look up the administered object stored in the JNDI service, as mentioned on Day 4, “Using JNDI for Naming Services and Components.”

InitialContext ctx = new InitialContext();
Session session = (Session) ctx.lookup("ursMailSession");

In the preceding snippet, ursMailSession is the JNDI name object used as the administered object for the Session object. ursMailSession can be created and configured with the required parameters as name/value pairs, including information such as the mail server hostname, the user account sending the mail, and the protocols supported by the Session object. Using this declarative approach as the default method when creating a Session object helps makes your application portable by not hardcoding any parameters inside your applications. Later today, we'll explain how to configure this administered Session object, in the WebLogic Server and JBoss server environments.

Note

As you learned on Day 4, the J2EE specification recommends that all resource manager connection factory references be organized in the subcontexts of the application component's environment, using a different subcontext for each resource manager type. According to Table 4.2, connection factories of JavaMail should be declared in the java:comp/env/mail subcontext.


The other method of creating the Session object is based on the programmatic approach in which you can use a java.util.Properties object to override some of the default information, such as the mail server name, username, password, and other information that can be shared across your entire application. As you learned, J2EE promotes portability, and always recommends the declarative approach over the programmatic approach to avoid hardcoding parameters.

Because the constructors for the Session class are private, you can get a single default Session that can be shared with other components using the getDefaultInstance() method:

Properties props = new Properties();
// Override props with your customized data
props.put("mail.transport.protocol", "smtp");
props.put("mail.host", "acme");
Session session = Session.getDefaultInstance(props, null);

Similarly, to create a unique Session object (not shared), you use the getInstance() method:

Session session = Session.getInstance(props, null);

In both cases, the null argument is an Authenticator object. More information about the Authenticator object will be given shortly.

In most cases, it's sufficient (also efficient) to use a shared Session, even if you're working with mail sessions for multiple user mailboxes. You can add the username and password combination at a later step in the communication process and keep everything separate.

Message

The Message object is the container for all parts of the e-mail message. After you've created a Session object, you can start composing messages to send. This is accomplished by using a concrete subclass of Message. Because Message is an abstract class, you must work with a subclass; in most cases, you'll use a MimeMessage (in javax.mail.internet). A MimeMessage is an e-mail message that understands MIME types and headers. Message headers are restricted to ASCII characters only, although non-ASCII characters can be encoded in certain header fields. MimeMessage acts as a container to hold all the parts of the message.

To create a Message, you pass the Session object as an argument to the MimeMessage constructor:

MimeMessage msg = new MimeMessage(session);

After you've created a new MimeMessage, you can start filling its parts. The Message class implements the Part interface (with MimeMessage implementing MimePart). To set the content, you use the setContent() method with arguments for the content and the MIME type. Here's an example of setting the message body with a plain text message:

msg.setContent("Hello World", "text/plain");

The special method setText() is used to set the text content (with MIME type of text/plain):

msg.setText("Hello World");

The setContent() method is used to set other kinds of MIME types, such as HTML e-mail messages.

The method setSubject() is used to set the subject of the message:

message.setSubject("Just Say Hello");

Other methods used to set various message properties will be discussed in the next sections.

Address

Address is an abstract class that represents an e-mail address, such as [email protected]. This represents any sender address (from) or recipient address (to). To create an Address object, you pass the e-mail address as a parameter to the InternetAddress subclass constructor:

Address address = new InternetAddress("[email protected]");

If you want the name to appear next to the e-mail address, you can pass that name along to the constructor:

Address address = new InternetAddress("[email protected]", "John Doe");

This method is used to create a valid e-mail address, whether you need to create address objects for the message's from field or the to field.

Note

You can send a message that appears to be from anyone, unless the mail server prevents you from doing so for security reasons.


You use the setFrom() method to set the sender address, and the setReplyTo() method to set the address to which the reply should be directed (where from and to are of type Address):

msg.setFrom(from);

msg.setReplyTo(to);

Caution

Not all message types allow the setReplyTo() method to be specified separately from the sender of the message.


You can send a message from multiple senders simply by creating the following:

Address address[0] = address1;
Address address[1] = address1;
...
msg.addFrom(address);

To set the message recipients, you use the addRecipient() method. This method requires a Message.RecipientType in addition to the address.

message.addRecipient(type, address)

The three predefined address types are objects with one of these values:

  • Message.RecipientType.TO for a primary recipient

  • Message.RecipientType.CC for a carbon copy recipient

  • Message.RecipientType.BCC for a blind carbon copy recipient

For example, to send a message to our friend John Doe and carbon copy [email protected], the following would be appropriate:

Address toAddress = new InternetAddress("[email protected]");
Address ccAddress = new InternetAddress("[email protected]");
message.addRecipient(Message.RecipientType.TO, toAddress);
message.addRecipient(Message.RecipientType.CC, ccAddress);

The JavaMail API provides no mechanism to check for the validity of an e-mail address. This is left to the e-mail server provider.

Authenticator

The JavaMail API can use an Authenticator object to access the e-mail server by using a username and password. Because it's an abstract class, you create a subclass PasswordAuthentication, passing a username and password to its constructor. You must register the Authenticator with the session when you create it, by replacing the null in the example shown in the “Session” section earlier today. Here's an example with the user jDoe and his pswrd:

Properties props = new Properties();
// Override props with any customized data
PasswordAuthentication auth = new PasswordAuthentication("jDoe", "pswrd")
Session session = Session.getDefaultInstance(props, auth);

Transport

The last task in sending an e-mail message is to use the Transport class. This class normally uses the SMTP protocol to send a message. An easy way to send a message is to use the default version of the class by calling the static send() method:

Transport.send(msg);

Here the static send() method makes a separate connection to the e-mail server for each method call. To enhance your application performance, we recommended keeping your connection to the mail server alive when sending multiple messages. To do so, you need to create a specific instance of the Transport object and not the default object. You pass the protocol along with the hostname, username, and password, send the messages, and then close the connection, as shown here:

MimeMessage msg1, msg2;
// ... Create and populate messages ...
Transport trans = session.getTransport("smtp");
trans.connect("mail.acme.com", "jDore", "pswrd");
trans.sendMessage(msg1, msg1.getAllRecipients());
trans.sendMessage(msg2, msg2.getAllRecipients());
trans.close();

To monitor your mail server while sending messages, you turn on your debug flag by using the setDebug() method of the Transport class:

session.setDebug(true);

The default parameter value is false, which turns off debugging.

Store and Folder

When you store and retrieve messages from your e-mail server, you must connect to a Store. A Store holds messages in different Folders on your server. After you create a Session object, you connect to a Store, and identify the e-mail server host, user ID, and password. Both the Transport and Store classes extend the Service class, which defines the connect() and close() methods. You need to tell the Store what protocol to use:

Store store = session.getStore("pop3");
store.connect(host, userid, password);

After you connect to a Store, you can get a Folder, open it, and start reading messages. The following is an example of how to read messages from the (reserved name) INBOX folder:

Folder folder = store.getFolder("INBOX");
folder.open(Folder.READ_ONLY);
Message message[] = folder.getMessages();

Note

The only folder available in POP3 is INBOX. If you're using IMAP, you can have other folders available.


The folder name is case sensitive. You open a folder in a read only or read/write mode. The latter mode enables you to delete messages. To create a new folder under the current folder, use the create() method. The delete() and the exists() methods delete and check whether a folder exists, respectively.

To read the contents of a message, use the getContent() method (without the message's header). The writeTo() method writes the message, including the message header, to a stream.

System.out.println(((MimeMessage)message).getContent());

After you've finished reading your e-mail, close the connection to the folder and store:

folder.close(true);
store.close();

In the preceding snippet, the true parameter value of the close() method indicates the removal of all deleted messages. Expunge is another term used to describe the deletion of messages.

The JavaBean Activation Framework

The JAF API is used by the JavaMail API to manage MIME data. The DataSource interface provides the JAF with an abstraction of some arbitrary collection of data. The FileDataSource class implements a simple DataSource object that encapsulates a file. This helps you include attachments of different file types in your messages. The following section demonstrates the use of these interfaces and classes to send messages with attachments.

..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset
18.191.168.203