Sometimes it's necessary, or just convenient, for a servlet to fire off an email message. For example, imagine a servlet that receives data from a user feedback form. The servlet might want to send the feedback data to a mailing list of interested parties. Or imagine a servlet that encounters an unexpected problem and knows to send an email page to its administrator asking for help.
A servlet has four choices for sending email:
It can manage the details itself--establishing a raw socket connection to a mail server and speaking a low-level mail transport protocol, usually the so-called Simple Mail Transfer Protocol (SMTP).
It can run on external command-line email program, if the server system has such a program.
It can use the new JavaMail API, designed to support complicated mail handling, filing, and processing (see http://java.sun.com/products/javamail).
It can use one of the many freely available mail classes that abstracts the details of sending email into simple, convenient method calls.
For most servlets, we recommend the final approach for its simplicity.
For the purposes of this example, we'll demonstrate a servlet that uses the sun.net.smtp.SmtpClient class. It's conveniently provided with Sun's JDK and most JVMs descended from it, but we should warn you that it's unsupported and subject to change (though it hasn't changed since JDK 1.0). Using it is simple:
Call SmtpClientsmtp=newSmtpClient(). Optionally, pass the constructor the name of a host to use as the mail server, which replaces the default of localhost. Most Unix machines can act as SMTP mail servers.
Call smtp.from(fromAddress), specifying the address of the sender. The address doesn't have to be valid.
Call smtp.to(toAddress), specifying the address of the receiver.
Call PrintStreammsg=smtp.startMessage() to get an output stream for the message.
Write any mail headers to the PrintStream. For example, "Subject: Customer feedback". The headers should conform to the format given in RFC 822 at http://www.ietf.org/rfc/rfc822.txt. The basic syntax is "name : value".
Write the body of the mail message to the PrintStream.
Call smtp.closeServer() to close the connection to the server and send the message.
Example 13-3 shows a servlet that emails the form data it receives to a mailing list. Notice the extensive use of the ParameterParser class.
import java.io.*; import java.util.*; import javax.servlet.*; import javax.servlet.http.*; import com.oreilly.servlet.ParameterParser; import com.oreilly.servlet.ServletUtils; import sun.net.smtp.SmtpClient; public class MailServlet extends HttpServlet { static final String FROM = "MailServlet"; static final String TO = "feedback-folks@attentive-company.com"; public void doGet(HttpServletRequest req, HttpServletResponse res) throws ServletException, IOException { res.setContentType("text/plain"); PrintWriter out = res.getWriter(); ParameterParser parser = new ParameterParser(req); String from = parser.getStringParameter("from", FROM); String to = parser.getStringParameter("to", TO); try { SmtpClient smtp = new SmtpClient(); // assume localhost smtp.from(from); smtp.to(to); PrintStream msg = smtp.startMessage(); msg.println("To: " + to); // so mailers will display the To: address msg.println("Subject: Customer feedback"); msg.println(); Enumeration enum = req.getParameterNames(); while (enum.hasMoreElements()) { String name = (String)enum.nextElement(); if (name.equals("to") || name.equals("from")) continue; // Skip to/from String value = parser.getStringParameter(name, null); msg.println(name + " = " + value); } msg.println(); msg.println("---"); msg.println("Sent by " + HttpUtils.getRequestURL(req)); smtp.closeServer(); out.println("Thanks for the submission..."); } catch (IOException e) { out.println("There was a problem handling the submission..."); getServletContext().log(e, "There was a problem sending email"); } } }
This servlet first determines the "from" and "to" addresses for the message. The default values are set in the FROM and TO variables, although a submitted form can include (probably hidden) fields that specify alternate from and to addresses. The servlet then begins an SMTP email message. It connects to the local host and addresses the message. Next, it sets its headers and fills the body with the form data, ignoring the to and from variables. Finally, it sends the message and thanks the user for the submission. If there's a problem, it informs the user and logs the exception.
Copyright © 2001 O'Reilly & Associates. All rights reserved.