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>]");
}
}
}