Section 15.1. Email and JavaMail


15.1. Email and JavaMail

The vast majority of JavaMail applications use the system to interact with Internet email. While it's safe to assume that anyone reading this book has some conceptual familiarity with electronic mail, a quick overview of Internet-based email from a technical perspective is in order. If you would like more details about email services, see Programming Internet Email by David Wood (O'Reilly).

The primary mechanism for email transport over the Internet is the Simple Mail Transfer Protocol (SMTP ), as defined in RFC 822. SMTP clients, such as desktop email programs, send messages by connecting to another SMTP server and transmitting a series of headers followed by a message body. Once the SMTP server receives a message, it is either stored for access by local users or forwarded to another SMTP server nearer to its destination. Most ISP and corporate mail servers will accept messages only for delivery to local users or from local users for delivery elsewhere. In the latter case, the SMTP server is responsible for determining the appropriate destination for the message.

If the SMTP server determines that a message is for local delivery (for instance, mail.oreilly.com handles incoming email for O'Reilly Media), it handles the message in a number of ways. Early SMTP-based email systems just stored the incoming messages in the Unix mailbox format for retrieval off the local disk by mail reader software. However, as systems grew and mail services became decoupled from other systems, a need arose for a standardized way to access centralized "post office" systems that pooled the incoming mail for an entire domain (or, in the case of many ISPs, multiple domains). At a minimum, this involved providing access to Unix mailboxes over the Internet. POP, which stands for Post Office Protocol, was the first successful attempt to do this. A mail client (such as Outlook, PINE, or Eudora) can use POP to connect to a POP server and download the messages waiting for a particular user. POP has subsequently been replaced with POP-3 (which is universally supported) and IMAP, a more flexible successor that has rapidly gained acceptance since Version 4 was introduced in 1994.

Figure 15-1 shows the path of a typical email message from the sender's email client to the recipient's email client. Note that this is a very simple case, with two SMTP servers relaying mail over the long haul (like AT&T long distance) and a or IMAP server at the receiving end (acting like a Baby Bell). Depending on server and client configurations, there may be only one SMTP server involved, or there may be several as messages are routed from ISP to ISP.

Figure 15-1. Basic email routing


15.1.1. JavaMail Layers

At this point, we'll give you a brief overview of the JavaMail layers . The abstract layer of the JavaMail APIs can be divided into three categories: sessions, services, and messages. Sessions contain information about the current user, mail hosts, and protocols. They serve as factories for various types of objects. Messages are exactly that: text sent through the mail system. Services allow you to do useful things with messages and are subdivided (as of JavaMail 1.2) into two categories: stores and transports. Stores act as containers for sets of messages, while transports route messages from one site to another.

As we mentioned earlier, most of the JavaMail API consists of abstract classes. When necessary, however, implementations of those classes are provided by an implementation layer. Implementation layers may include SMTP, IMAP, NNTP, or POP-3 protocols or a message storage system. The implementation layer handles the actual message processing tasks.

15.1.2. Installing and Configuring JavaMail

If you're using J2EE 1.3 or 1.4, which include JavaMail 1.2 and 1.3 respectively, you need not download JavaMail. Otherwise, you can download the standalone JavaMail 1.3 distribution, suitable for inclusion in any application, from http://java.sun.com/products/javamail. You will also need the JavaBeans Activation Framework, which contains the javax.activation classes used to handle certain content formatting tasks. JAF is available from http://java.sun.com/products/javabeans/jaf.

If you're not in a full J2EE configuration, install JavaMail by adding JAF's activation.jar and JavaMail's mail.jar to your system CLASSPATH or your JDK's lib directory. If you look at the JavaMail archive, you'll notice some additional jars: mailapi.jar, imap.jar, smtp.jar, and pop3.jar. The mail.jar file contains the contents of all four files, but you can use the smaller jars to selectively include service implementations in your environment. Using the smaller jar files helps reduce loading time for applets. Note that some J2EE application servers may package the JavaMail and JAF classes differently. Consult your server's documentation for details.

By simply adding these jar files to the CLASSPATH, most JavaMail programs should compile and execute. However, some additional configuration options are available. JavaMail allows you to set a number of system properties to provide email-related system defaults. In addition to the eight properties listed in Table 15-1, each service has its own set of specific properties. Note that you don't need to set any of these to use the APIs.

Table 15-1. Core JavaMail environment properties

Property

Description

Default

mail.store.protocol

Default message store protocol (such as POP or IMAP).

First message store specified in the JavaMail configuration files

mail.transport.protocol

Default message transport protocol (such as SMTP).

First transport specified in the JavaMail configuration files

mail.host

Default host. JavaMail providers will attempt to connect to this system if no other host is specified.

The local machine

mail.user

Default username to use when connecting to a provider.

user.name

mail.protocol.host

Default host for a particular protocol. To set the default IMAP host, use mail.imap.host. Overrides mail.host .

Value of mail.host

mail.protocol.user

Default user for a particular protocol. To set the default IMAP user, use mail.imap.user.

Value of mail.user

mail.from

Return address of the current user.

username@host

mail.debug

Whether JavaMail should operate in debug mode. Debug mode can also be toggled via the setDebug( ) method of Session.

false


15.1.2.1. Provider registries

JavaMail is designed to allow third parties to provide service implementations. JavaMail identifies the installed providers via the javamail.providers and javamail.address.map registry files. When starting up a JavaMail session, the system searches for javamail.providers files in the following locations:[*]

[*] Note that under JDK 1.1, only one META-INF/javamail.providers file can be found due to classloader limitations.

  • JAVA_HOME/lib/javamail.providers

  • META-INF/javamail.providers (in application jar files)

  • META-INF/javamail.default.providers (in application jar files; generally found only in the JavaMail mail.jar file)

The first entries found provide the defaults unless specifically changed by the application; if two POP3 providers are found, the first one identified becomes the default.

The javamail.providers file is formatted like this:

     protocol=imap; type=store;     class=com.sun.mail.imap.IMAPStore;     vendor=SunMicrosystems,Inc;     version=1.2; 

The semicolon is the field delimiter. The javamail.address.map file is located in the same fashion as javamail.providers (including the javamail.default.address.map file in mail.jar) and contains mappings of address types to transport services. For example, messages to RFC 822-formatted addresses are transported via the SMTP protocol, and this relationship is indicated by a line in the javamail.address.map file like this one:

     rfc822=smtp 

Unless you are developing your own service providers, you probably won't need to alter any of these files.

15.1.3. The Mail Session

As we mentioned earlier, the JavaMail API provides a Session class that fills two roles. First, it stores messaging-related properties, both global and user-specific, and provides this information to most new JavaMail objects via their constructors. Second, it provides factory methods for Store and transport objects.

The JavaMail API provides two types of Session objects: the default session and local sessions . The default session is created only once using the static Session.getDefaultInstance( ) method. There are two overloaded versions of the getdefaultInstance( ) method: one accepts a java.util.Properties object, and one accepts a Properties object and a javax.mail.Authenticator. The Properties object can be use to set JavaMail system properties.[*] The Authenticator can also be used to limit access to the default session; if the first call to getdefaultInstance( ) includes an Authenticator, all subsequent calls must pass either the same instance of the Authenticator object or an instance from the same class loader as the original Authenticator object. Note that no Authenticator implementations are provided with the basic JavaMail distributionyou have to create your own by subclassing the abstract javax.mail.Authenticator class provided by the API.

[*] The Properties-only version of this method was added in the JavaMail 1.2 release, so if you are running against a stock J2EE 1.2 installation or the JavaMail 1.1 release, you won't find it. Everything else in this chapter should apply equally to Versions 1.1 and 1.2.

The Session.getInstance( ) method behaves the same as geTDefaultInstance( ), but also provides a local instance of the Session object that is not shared across the JVM. With this approach, the Authenticator is used only to determine usernames and passwords for services that require them.

The following code sample retrieves a default session, using the JVM system properties to define JavaMail properties and using an Authenticator implementation called myAuthenticator. It then tries to retrieve a second reference to the default session without using an authenticator. If this fails (which, in this case, it will), the code gets a local instance instead.

     Session session = Session.getDefaultInstance(System.getProperties( ),                                                  new MyAuthenticator( ));     // Try to get it again, without the authenticator; get local     // instance on failure     Session sess2 = null;     try {       sess2 = Session.getDefaultInstance(System.getProperties( ), null);       } catch(SecurityException se) {         sess2 = Session.getInstance(System.getProperties( ), null);     } 

15.1.3.1. Authenticators

Besides controlling access to the default session, javax.mail.Authenticator objects are also used to provide usernames and passwords to messaging services such as mail servers. This is accomplished by extending the abstract Authenticator class and overriding the getPasswordAuthentication( ) method, which returns a JavaMail PasswordAuthentication object:

     class BasicAuthenticator extends Authenticator {       protected PasswordAuthentication getPasswordAuthentication( ) {         return new PasswordAuthentication("scott", "tw7182");       } 

The PasswordAuthentication object is simple: it just serves as a container for the two strings. In most applications, these would be entered by the user via a dialog box or retrieved from some centralized directory service. Since Authenticator objects are global to the session, the base Authenticator class contains a number of final methods, which can be used to provide information about the particular authentication requestfor instance, using getrequestingProtocol( ) and getrequestingSite( ), the getPasswordAuthentication( ) code can determine whether to provide the IMAP login information for mailserver.myco.com or the POP3 login information for pop.prep.edu.

15.1.3.2. Providers

A Session itself doesn't provide any mail-handling capabilitiesit simply provides the means to access other messaging services. Generally, you will know what sort of messaging protocols and services are available before sitting down to code your application and won't need to determine them on the fly. However, the javax.mail.Provider object provides a convenient view of the implementation details for particular services: the protocol (such as SMTP), the service type (message storage or message transport), vendor, version, and implementing class name.

For most applications, you don't actually need to worry about the Provider object, because you don't need access to the object itself to access the features it provides. However, if you do need one, the getProviders( ) method of Session will allow you to interrogate the current session to determine which service providers are installed. This method returns an array of Provider objects describing the different protocol implementations available to the session. To retrieve the Provider object for a particular protocol, call the getProvider(String) method and pass it the protocol name, as in the following:

     mySession.getProvider("smtp"); 

By default, provider information is specified in the javamail.providers and javamail.default.providers resource files. This means that if you are using the providers in the Sun JavaMail distribution, you don't have to do anything to obtain access to the standard services. If you want to programmatically install your own implementation of a particular protocol, you can pass a vendor-supplied Provider object to the setProvider( ) method of Session.

15.1.3.3. URL names

JavaMail provides a number of mechanisms for identifying services, including the system properties discussed earlier in this chapter. JavaMail services can also be identified via URLs in the form protocol://server. An IMAP URL, for example, might look like imap://mailserver.cs.edu. The javax.mail.URLName object is used to encapsulate information about a connection to a mail service. This can be quite convenient, since it allows all necessary information about a connection to be assembled in a centralized location. Since service URLs are protocol-specific, this can include an arbitrary range of precision IMAP URLs, for instance, allow the specification of particular messages and folders within the IMAP message store.[*]

[*] RFC 2192 contains full information about the IMAP URL scheme. It can be found online at http://www.faqs.org/rfcs/rfc2192.html.

A URLName object is only a container for connection informationhence the "Name." It doesn't actually connect to the service it identifies. Instead, it can be passed to various methods of Session, including getFolder( ), getStore( ), and gettransport( ).

URLName objects can be retrieved from existing service connections via the getURLName( ) method of Service (we'll look at specific services later in this chapter). They can also be created directly via three constructors:

     URLName(Stringurl)     URLName(java.net.URLurl)     URLName(java.lang.String protocol, java.lang.String host, int port,             java.lang.String file, java.lang.String username,             java.lang.String password) 

The first two are fairly straightforward, accepting a raw URL in a String format or encapsulated as a java.net.URL object. The third optionthe detailed constructorallows you to build up the URL from its individual components, including some components (i.e., password) that might not be included in the actual URL at all. Not all options apply to all protocols, so to keep the default value for each field, pass in null. The obvious exception is the port parameter, which accepts -1 as its default value indicator.

The other way to associate login information with a URLName (particularly if the URLName was created by some mechanism other than the detailed constructor) is to associate a PasswordAuthentication object with the URL. This is done at the session level by using Session.setPasswordAuthentication(URLName, PasswordAuthentication) and Session.getPasswordAuthentication(URLName). Once a PasswordAuthentication object has been associated with a URLName, it will be used to handle authentication for future connections to that URL.



Java Enterprise in a Nutshell
Java Enterprise in a Nutshell (In a Nutshell (OReilly))
ISBN: 0596101422
EAN: 2147483647
Year: 2004
Pages: 269

flylib.com © 2008-2017.
If you may any questions please contact us: flylib@qtcs.net