Recipe 20.6 Handling Attachments from an Email Received in a Servlet


Problem

You want to read an email message and save any attachments from a servlet.

Solution

Use the JavaMail API and a special JavaBean to save the InputStream s from attached files to a specified folder.

Discussion

Accessing email usually involves authenticating a user with a POP account, then connecting with the mail server and downloading any email messages. Example 20-6 uses the Session , Store , Folder , and Message classes from the JavaMail API to download an array of Messages from a particular user's email account. However, the servlet in Recipe 20.4 was designed to deal only with Messages whose content was of type String (the return value of the Message.getContent( ) method).

If the Message 's content is of type Multipart , then the process of handling attachments mirrors the peeling of an onion ”more code is involved. Example 20-6 separates the email- related code into a JavaBean that can be used from a servlet. The bean's displayMessage( ) method tests the content of each Message . If the content is of type Multipart , then the code examines each contained BodyPart .

Picture a Multipart message type as a container. The container's headers are like any other email message's headers (but with different values). The container encloses BodyPart s, which are like messages inside of messages. Some BodyPart s represent the text message accompanying a Multipart email message. Other BodyPart s represent the attached files, such as a Microsoft Word file or JPEG image.


If the BodyPart 's content is a String , then the bean displays the text message. Otherwise, the bean assumes the BodyPart is an attached file; it saves the file to a special attachments folder. You're probably already familiar with the handleMessages( ) code, so you can skip to the displayMessage( ) method, which deals with saving any file attachments.

Example 20-6. A JavaBean that handles attachments and delivers a browser message
 package com.jspservletcookbook;     import java.io.*; import java.util.Properties;  import javax.mail.*; import javax.mail.internet.*;  import javax.servlet.*; import javax.servlet.http.*; public class AttachBean  {   /* NOT SHOWN: private bean fields (or, properties); default variables;      and the sendMessage method      See Example 20-2 */   public AttachBean( ){}  private void handleMessages(HttpServletRequest request,        PrintWriter out) throws IOException, ServletException {  /* get the user and password information for a POP           account from an HttpSession object */        HttpSession httpSession =  request.getSession( );        String user = (String) httpSession.getAttribute("user");        String password = (String) httpSession.getAttribute("pass");        String popAddr = (String) httpSession.getAttribute("pop");  Store popStore = null;        Folder folder = null;  if (! check(popAddr))            popAddr = AttachBean.DEFAULT_SERVER;             try {                if ((! check(user))  (! check(password)))             throw new ServletException(             "A valid username and password is required to check email.");  Properties properties = System.getProperties( );            Session session = Session.getDefaultInstance(properties);            popStore = session.getStore("pop3");            popStore.connect(popAddr, user, password);            folder = popStore.getFolder("INBOX");            if (! folder.exists( ))                throw new ServletException(                  "An 'INBOX' folder does not exist for the user.");                    folder.open(Folder.READ_ONLY);            Message[] messages = folder.getMessages( );  int msgLen = messages.length;            if (msgLen == 0)                out.println(                  "<h2>The INBOX folder does not yet contain any " +                  " email messages.</h2>");  for (int i = 0; i < msgLen; i++){                       displayMessage(messages[i], out);                out.println("<br /><br />");            }//for  } catch (Exception exc) {                  out.println(             "<h2>Sorry, an error occurred while accessing " +             "the email messages.</h2>");             out.println(exc.toString( ));  } finally {             try{                             if (folder != null)                    folder.close(false);                             if (popStore != null)                   popStore.close( );                            } catch (Exception e) { }        }     }//handleMessages              private void displayMessage(Message msg, PrintWriter out)          throws MessagingException, IOException{                  if (msg != null){                      /* get the content of the message; the message could                be an email without attachments, or an email                with attachments. The method getContent( ) will return an                instance of 'Multipart' if the msg has attachments */             Object o = msg.getContent( );                  if ( o instanceof String){                                  //just display some info about the message content                 handleStringMessage(msg,(String) o, out);                        } else if ( o instanceof Multipart ) {                                  //save the attachment(s) to a folder                 Multipart mpart = (Multipart) o;                 Part part = null;                 File file = null;                 FileOutputStream stream = null;                 InputStream input = null;                 String fileName = "";                                //each Multipart is made up of 'BodyParts' that                 //are of type 'Part'                 for (int i = 0; i < mpart.getCount( ); i++){                                        part = mpart.getBodyPart(i);                     Object partContent = part.getContent( );                                        if (partContent instanceof String){                         handleStringMessage(msg,(String) partContent,                           out);                                         }  else {//handle as a file attachment                                          fileName = part.getFileName( );                                        if (! check(fileName)){//default file name                            fileName = "file"+                                new java.util.Date( ).getTime( );}                                                //write the attachment's InputStream to a file                         file = new File( attachFolder +                         System.getProperty("file.separator") + fileName);                         stream = new FileOutputstream(file);                         input = part.getInputStream( );                         int ch;                                           while ( (ch = input.read( )) != -1){                            stream.write(ch);}                                                    input.close( );                          out.println(                           "Handled attachment named: "+                               fileName+"<br /><br />");                     }// if                 }//for             }//else if instanceof multipart           } else{                    out.println(                "<h2>The received email message returned null.</h2>");                 }// if msg != null               }//displayMessage              private void handleStringMessage(Part part, String emailContent,         PrintWriter out)  throws MessagingException {            if (part instanceof Message){           Message msg = (Message) part;           if (msg.getFrom( )[0] instanceof InternetAddress){                         out.println("Message received from: " +                ((InternetAddress) msg.getFrom( )[0]).getAddress( ) +                  "<br />");           }                             out.println(                 "Message content type: " + msg.getContentType( ) +                   "<br />");               out.println("Message content: " + emailContent +"<br />");       }  }        private boolean check(String value){            if(value == null  value.equals(""))           return false;                    return true;   }//check  /* NOT SHOWN: various 'setter' methods for the bean's properties      See Example 20-2 */  }// AttachBean 

Once the displayMessage( ) code identifies a BodyPart as an attached file, it receives the bytes that represent the file as an InputStream . A BodyPart implements the Part interface, which defines the method getInputStream( ) . The code saves the file using the InputStream and the java.io.FileOutputStream class.

Example 20-7 shows the doGet( ) method of a servlet using com.jspservletcookbook.AttachBean .

Example 20-7. A servlet's doGet( ) method uses a JavaBean to deal with email attachments
 public void doGet(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>");  AttachBean emailer = new AttachBean( );       emailer.setSmtpHost("mail.attbi.com");       emailer.setAttachFolder(getServletContext( ).getRealPath("/") + "attachments");       emailer.handleMessages(request,out);  out.println("</body></html>");   }//doGet 

Figure 20-2 shows the messages that the servlet (using the JavaBean) displays in a browser. The first email is a simple text message without attachments. The second email contains two attachments; its MIME type is multipart/mixed .

Figure 20-2. A servlet displays information about received attachments and messages
figs/jsjc_2002.gif

See Also

Sun Microsystem's JavaMail API page: http://java.sun.com/products/javamail/; 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.7 on adding attachments to an email message; 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

Similar book on Amazon

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