Recipe 20.7 Adding Attachments to an Email in a Servlet


Problem

You want to build an email message with attachments in a servlet.

Solution

Use the JavaMail API for basic email messaging, and the the JavaBeans Activation Framework (JAF) to generate the file attachments.

Discussion

The JAF classes provide fine-grained control over setting up a file attachment for an email message.

If you are using both the JavaMail API and the JAF, make sure to import the packages in your servlet class:

 import javax.activation.*; import javax.mail.*; import javax.mail.internet.*; //class definition continues 

The sendMessage( ) method in Example 20-8 creates a new email message ( specifically , a new javax.mail.internet.MimeMessage ), adds its text message, and inserts a file attachment inside the message. The method then sends the message using the code you may have seen in Recipe 20.2 and Recipe 20.3:

 Transport.send(mailMsg); 

To accomplish this, the code creates a container (a javax.mail.Multipart object) and two javax.mail.BodyPart s that make up the the container. The first BodyPart is a text message (used usually to describe the file attachment to the user ), while the second BodyPart is the file attachment (in this case, a Microsoft Word file). Then the code sets the content of the MimeMessage to the Multipart . In a nutshell , the MimeMessage (an email message) contains a Multipart , which itself is composed of two BodyPart s: the email's text message and an attached file.

If you want to look at the headers of a MimeMessage that contains attachments, call the getAllHeaders( ) method on the MimeMessage . See Recipe 20.8 for details.


Example 20-8. Making email attachment in a servlets
 package com.jspservletcookbook;     import java.io.*; import java.util.Properties;  import javax.activation.*; import javax.mail.*; import javax.mail.internet.*;  import javax.servlet.*; import javax.servlet.http.*; public class EmailAttachServlet extends HttpServlet {    //default value for mail server address, in case the user     //doesn't provide one    private final static String DEFAULT_SERVER = "mail.attbi.com";   public void doPost(HttpServletRequest request,      HttpServletResponse response) throws ServletException,       java.io.IOException {            response.setContentType("text/html");       java.io.PrintWriter out = response.getWriter( );       out.println(         "<html><head><title>Email message sender</title></head><body>");             String smtpServ = request.getParameter("smtp");       if (smtpServ == null  smtpServ.equals(""))         smtpServ = DEFAULT_SERVER;       String from = request.getParameter("from");       String to = request.getParameter("to");       String subject = request.getParameter("subject");       try {           sendMessage(smtpServ, to, from, subject);       } catch (Exception e) {           throw new ServletException(e.getMessage( ));        }       out.println(         "<H2>Your attachment has been sent.</H2>");       out.println("</body></html>");   }//doPost         public void doGet(HttpServletRequest request,      HttpServletResponse response) throws ServletException,         java.io.IOException {                  doPost(request,response);              }//doGet  private void sendMessage(String smtpServ, String to, String from,     String subject) throws Exception {             Multipart multipart = null;       BodyPart bpart1 = null;       BodyPart bpart2 = null;  Properties properties = System.getProperties( );       //populate the 'Properties' object with the mail       //server address, so that the default 'Session'       //instance can use it.       properties.put("mail.smtp.host", smtpServ);       Session session = Session.getDefaultInstance(properties);       Message mailMsg = new MimeMessage(session);//a new email message       InternetAddress[] addresses = null;            try {               if (to != null) {                        //throws 'AddressException' if the 'to' email address               //violates RFC822 syntax               addresses = InternetAddress.parse(to, false);               mailMsg.setRecipients(Message.RecipientType.TO, addresses);                    } else {               throw new MessagingException(                 "The mail message requires a 'To' address.");           }           if (from != null) {               mailMsg.setFrom(new InternetAddress(from));           } else {                        throw new MessagingException(                 "The mail message requires a valid 'From' address.");           }                     if (subject != null)             mailMsg.setSubject(subject);  //This email message's content is a 'Multipart' type           //The MIME type for the message's content is 'multipart/mixed'           multipart = new MimeMultipart( );                    //The text part of this multipart email message           bpart1 = new MimeBodyPart( );           String textPart =            "Hello, just thought you'd be interested in this Word file.";                    // create the DataHandler object for the text part           DataHandler data = new DataHandler(textPart, "text/plain");                    //set the text BodyPart's DataHandler           bpart1.setDataHandler(data);                    //add the text BodyPart to the Multipart container           multipart.addBodyPart( bpart1);           //create the BodyPart that represents the attached Word file           bpart2 = new MimeBodyPart( );           //create the DataHandler that points to a File           FileDataSource fds = new FileDataSource( new File(           "h:/book/chapters/chap1/chap1.doc") );                    //Make sure that the attached file is handled as           //the appropriate MIME type: application/msword here           MimetypesFileTypeMap ftm = new MimetypesFileTypeMap( );                    //the syntax here is the MIME type followed by           //space separated extensions           ftm.addMimeTypes("application/msword doc DOC" );                    fds.setFileTypeMap(ftm);           //The DataHandler is instantiated with the           //FileDataSource we just created           DataHandler fileData = new DataHandler( fds );           //the BodyPart will contain the word processing file           bpart2.setDataHandler(fileData);                    //add the second BodyPart, the one containing the attachment, to           //the Multipart object           multipart.addBodyPart( bpart2 );                    //finally, set the content of the MimeMessage to the           //Multipart object           mailMsg.setContent( multipart );                     // send the mail message; throws a 'SendFailedException'            //if any of the message's recipients have an invalid adress           Transport.send(mailMsg);  } catch (Exception exc) {                throw exc;                }//try   }//sendMessage }//EmailAttachServlet 

The comments in Example 20-8 explain what happens when you use the javax.activation classes to create a file attachment of the intended MIME type. The most confusing part is creating a javax.activation.FileDataSource that points to the file that you want to attach to the email message. The code uses the FileDataSource to instantiate the javax.activation.DataHandler , which is responsible for the content of the file attachment.

 //create the DataHandler that points to a File FileDataSource fds = new FileDataSource( new File(   "h:/book/chapters/chap1/chap1.doc") ); 

Make sure that the MimeMessage identifies the attached file as a MIME type of application/msword , so that the user's email application can try to handle the attachment as a Microsoft Word file. Set the FileTypeMap of the FileDataSource with the following code:

 //Make sure that the attached file is handled as //the appropriate MIME type: application/msword here MimetypesFileTypeMap ftm = new MimetypesFileTypeMap( );          //the syntax here is the MIME type followed by //space separated extensions ftm.addMimeTypes("application/msword doc DOC" );          fds.setFileTypeMap(ftm); 

A MimetypesFileTypeMap is a class that associates MIME types (like application/msword ) with file extensions such as .doc .

Make sure you associate the correct MIME type with the file that you are sending as an attachment, since you explicitly make this association in the code. See http://java.sun.com/j2ee/1.4/docs/api/javax/activation/MimetypesFileTypeMap.html for further details.


Then the code performs the following steps:

  1. Creates a DataHandler by passing this FileDataSource in as a constructor parameter.

  2. Sets the content of the BodyPart with that DataHandler .

  3. Adds the BodyPart to the Multipart object (which in turn represents the content of the email message).

See Also

Sun Microsystem's JavaMail API page: http://java.sun.com/products/javamail/; the JAF web page: http://java.sun.com/products/javabeans/glasgow/jaf.html; Recipe 20.1 on adding JavaMail- related JARs to your web application; Recipe 20.2 on sending email from a servlet; Recipe 20.3 on sending email using a JavaBean; Recipe 20.4 covering how to access email in a servlet; Recipe 20.5 on accessing email with a JavaBean; Recipe 20.6 on handling attachments in a servlet; Recipe 20.8 on reading an email's headers.



Java Servlet & JSP Cookbook
Java Servlet & JSP Cookbook
ISBN: 0596005725
EAN: 2147483647
Year: 2004
Pages: 326

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