8.4. Sending an Email MessageCreating and sending an email message with JavaMail requires the following steps:
JavaMail requires a lot of low-level tedious API calls to send an email message, so we've encapsulated everything into the TextEmail utility object in Example 8-2. Example 8-2. TextEmail.javapackage com.jbossatwork.util; import javax.mail.*; import javax.mail.internet.*; import java.util.*; /** * TextEmail defines utility methods for the JavaMail API, which provides * a platform independent and protocol independent framework to build Java * technology-based mail and messaging applications. * */ public class TextEmail { ... private Session session; private InternetAddress sender = new InternetAddress( ); private String subject = new String( ); private StringBuffer body = new StringBuffer( ); private List recipients = new ArrayList( ); ... public TextEmail(Session session) throws EmailException { setSession(session); } ... public void setSession(Session session) { this.session = session; } ... public void send( ) throws EmailException { try { ... InternetAddress[ ] recipientsArr = (InternetAddress[ ]) recipients.toArray(new InternetAddress[0]); // Create a New message. MimeMessage msg = new MimeMessage(session); // Set the "From" address. msg.setFrom(sender); // Set the "To recipients" addresses. msg.setRecipients(Message.RecipientType.TO, recipientsArr); ... // Set the Subject. msg.setSubject(subject); // Set the Text. msg.setText(body.toString( )); // Set the sent date. msg.setSentDate(getSentDate( )); // Send the message. Transport.send(msg); } catch (MessagingException me) { throw new EmailException(me); } } } We left out the getter and setter methods for the sender, subject, body, and recipients data members to shorten the code example above, but you can look at the full TextEmail class in the book's code distribution. The send( ) method first converts the list of recipients from Strings to InternetAddresses that represent email addresses in the standard RFC822 formatsomething like name@host.domain is a common syntax. The MimeMessage constructor takes a JavaMail Session and instantiates the JavaMail message. We'll talk more about JavaMail Sessions in the next section. The message's setFrom( ) method sets the sender's email address, and the message's setRecipients( ) call sets the required recipients list. The message's setSubject( ) method sets the email message's subject line and the MimeMessage's setText( ) method sets the email message's body text. The message's setSentDate( ) method sets the email message's sent date, and the transport.send( ) call sends the message. 8.4.1. JavaMail SessionsA JavaMail Session represents a connection to a JavaMail provider that enables an application to send or receive email messages. After looking at the TextEmail code above, you may be thinking, "I already know JavaMail, so how is this different from what I've done before?" You may be familiar with setting JavaMail properties and using the Session.getDefaultInstance( ) method to get a JavaMail Session. You've probably written code that looks like Example 8-3. Example 8-3. TextEmail.javaprivate Session getDefaultSession( ) { Properties props = new Properties( ); props.setProperty("mail.store.protocol", "pop3"); props.setProperty("mail.pop3.host", "mail.isp.host.name"); props.setProperty("mail.transport.protocol", "smtp"); props.setProperty("mail.smtp.host", "smtp.isp.host.name"); props.setProperty("mail.smtp.port", "25"); // Get the default Session using Properties. Session session = Session.getDefaultInstance(props); return session; } In the example above, we use Sun's default JavaMail provider and supply an email server's Simple Mail Transfer Protocol (SMTP) and Post Office Protocol (POP) properties to get a JavaMail Session. Your email service provider also may require a user ID and password. When creating a JavaMail Session, you can use either Sun's default JavaMail provider (as shown in the above getdefaultSession( ) method ) or the JavaMail provider that comes with JBoss (using JNDI, as shown in the CreditCheckProcessorBean's sendNotificationEmail( ) method). If your code runs inside the JBoss application server, we recommend using the JBoss JavaMail provider because:
The JAW Motors application uses JBoss' JavaMail provider by using a JNDI lookup to find the JavaMail Session associated with the JBoss server instance. We've wrapped the JavaMail API calls in the TextEmail utility to make it easy to send an email message with the JavaMail API. The CreditCheckProcessorBean used the ServiceLocator utility to find the JavaMail Session that uses JNDI. Let's take a closer look at the ServiceLocator. 8.4.2. Factoring out the JNDI CallsWe've used the ServiceLocator throughout this book to wrap JNDI lookup calls Example 8-4 shows the new JavaMail-related method. Example 8-4. ServiceLocator.javapackage com.jbossatwork.util; ... import javax.naming.*; ... public class ServiceLocator { ... public static javax.mail.Session getJavaMailSession( String javaMailSessionJndiName) throws ServiceLocatorException { javax.mail.Session javaMailSession = null; try { Context ctx = new InitialContext( ); javaMailSession = (javax.mail.Session) ctx.lookup(javaMailSessionJndiName); } catch (ClassCastException cce) { throw new ServiceLocatorException(cce); } catch (NamingException ne) { throw new ServiceLocatorException(ne); } return javaMailSession; } ... } The getJavaMailSession( ) method encapsulates a JNDI lookup for JavaMail Session by taking the following steps:
We've written all the necessary code to send an email message with the JavaMail API, and now we need to add JavaMail to our deployment. We'll start by adding JavaMail-based JNDI references to our EJB deployment descriptors. |