[ Team LiB ] Previous Section Next Section

5.3 Sending Email Through a URLConnection

As mentioned earlier, Java includes support for different URL protocols through protocol handlers that are implemented internally to the Java SDK. These handlers include support for the mailto: protocol. Example 5-3 shows a program that uses a mailto: URL to send email. The program prompts the user to enter the sender, recipient or recipients, subject, and body of the message, and then creates an appropriate mailto: URL and obtains a URLConnection object for it. The program uses the setDoInput( ) and setDoOutput( ) methods to specify that it is writing data to the URLConnection. It obtains the appropriate stream with getOutputStream( ) and then writes the message headers and body to that stream, closing the stream when the message body is complete. The program uses the user.name system property and the InetAddress class to attempt to create a valid return address for the sender of the email, though this doesn't actually work correctly on all platforms.

In order for the mailto: protocol handler to send mail, it must know what computer, or mailhost, to send it to. By default, it attempts to send it to the machine on which it is running. Some computers, particularly Unix machines on intranets, work as mailhosts, so this works fine. Other computers, such as PCs connected to the Internet by a dialup connection, have to specify a mailhost explicitly on the command line. For example, if your Internet service provider has the domain name isp.net, the appropriate mailhost is often mail.isp.net or smtp.isp.net. If you specify a mailhost, it is stored in the system property mail.host, which is read by the internal mailto: protocol handler.

Note that Example 5-3 uses the println( ) method to display messages to the console but uses the print( ) method and explicit "\r\n" line terminator characters to send text over the network. Different operating systems use different line terminators, and println( ) uses whatever terminator is expected on the local system. The standard line terminator for network services, however, is the two-character sequence "\r\n". We use it explicitly here, so that this client program works correctly regardless of the platform-specific line terminator.

Example 5-3. SendMail.java
package je3.net;
import java.io.*;
import java.net.*;

/**
 * This program sends e-mail using a mailto: URL
 **/
public class SendMail {
    public static void main(String[  ] args) {
        try {
            // If the user specified a mailhost, tell the system about it.
            if (args.length >= 1)
                System.getProperties( ).put("mail.host", args[0]);
            
            // A Reader stream to read from the console
            BufferedReader in =
                new BufferedReader(new InputStreamReader(System.in));
            
            // Ask the user for the from, to, and subject lines
            System.out.print("From: ");
            String from = in.readLine( );
            System.out.print("To: ");
            String to = in.readLine( );
            System.out.print("Subject: ");
            String subject = in.readLine( );
            
            // Establish a network connection for sending mail
            URL u = new URL("mailto:" + to);      // Create a mailto: URL 
            URLConnection c = u.openConnection( ); // Create its URLConnection
            c.setDoInput(false);                  // Specify no input from it
            c.setDoOutput(true);                  // Specify we'll do output
            System.out.println("Connecting...");  // Tell the user
            System.out.flush( );                   // Tell them right now
            c.connect( );                          // Connect to mail host
            PrintWriter out =                     // Get output stream to host
                new PrintWriter(new OutputStreamWriter(c.getOutputStream( )));

            // We're talking to the SMTP server now.
            // Write out mail headers.  Don't let users fake the From address
            out.print("From: \"" + from + "\" <" +
                      System.getProperty("user.name") + "@" + 
                      InetAddress.getLocalHost( ).getHostName( ) + ">\r\n");
            out.print("To: " + to + "\r\n");
            out.print("Subject: " + subject + "\r\n");
            out.print("\r\n");  // blank line to end the list of headers

            // Now ask the user to enter the body of the message
            System.out.println("Enter the message. " + 
                               "End with a '.' on a line by itself.");
            // Read message line by line and send it out.
            String line;
            for(;;) {
                line = in.readLine( );
                if ((line == null) || line.equals(".")) break;
                out.print(line + "\r\n");
            }
            
            // Close (and flush) the stream to terminate the message 
            out.close( );
            // Tell the user it was successfully sent.
            System.out.println("Message sent.");
        }
        catch (Exception e) {  // Handle any exceptions, print error message.
            System.err.println(e);
            System.err.println("Usage: java SendMail [<mailhost>]");
        }
    }
}
    [ Team LiB ] Previous Section Next Section