[ Team LiB ] |
![]() ![]() |
Recipe 20.6 Handling Attachments from an Email Received in a ServletProblemYou want to read an email message and save any attachments from a servlet. SolutionUse the JavaMail API and a special JavaBean to save the InputStreams from attached files to a specified folder. DiscussionAccessing 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.
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 messagepackage 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![]() See AlsoSun 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. |
[ Team LiB ] |
![]() ![]() |