Section 15.4. Multipart Messages


15.4. Multipart Messages

Up until now, we haven't discussed viewing or creating messages except at a very simplistic level. Let's close this chapter by taking a look at the MimeMessage class, the standard Message implementation for Internet email, and the Multipart class, which allows MIME-formatted messages that contain multiple parts (for instance, text and HTML versions of content and file attachments).

15.4.1. Displaying Multipart Messages

MimeMessage objects are either single part or multipart. A single-part message has a content-type attribute matching the content of the message (often "text/plain"); the actual message content is stored in the message's content attribute, accessed via the getContent( ) method.

Multipart messages of content types begin with "multipart" and contain a Multipart object as their content. The Multipart object contains a series of BodyPart objects (in the case of a MIME-formatted message, these will be MimeBodyPart objects and can be cast as such). Each BodyPart has its own content type and associated content.

The getContent( ) and getContentType( ) methods of Message are actually inherited from the Part interface, which is also implemented by BodyPart and MimeBodyPart. Part provides another useful method, isMimeType( ), which allows testing for particular content types. The isMimeType( ) method will compare only the primary and subcontent types (the types immediately before and after the / character). So, isMimeType("text/plain") will return true if the MIME type is "text/plain" or "text/plain; charset=USASCII." You use the wildcard character * in place of the subtype (for example, "text/*") to match all data with a particular primary type.

Example 15-4 is an enhanced version of the mail viewer from Example 15-2 (although it just pulls from a single source). It starts by connecting to a POP server and downloading copies of the messages in the inbox. For each message, the program displays subject and senders and determines whether the message is multipart or not. If it is, the Multipart object is retrieved and each individual part is processed. Textual content is written to the screen. Nontextual content with a filename associated with it, such as a file attachment, is written to disk and the path is displayed.

Example 15-4. Multipart display
 import javax.mail.*; import javax.mail.internet.*; import java.io.*; public class MimeShow { static String mailhost = "pop.company.com"; public static void main(String[] args) {   Session session = Session.getDefaultInstance(                                                System.getProperties( ), null);   try {     Store popStore = session.getStore("pop3");     popStore.connect(mailhost, "username", "password");     // Get a default folder, and use it to open a real folder     Folder defaultPopFolder = popStore.getDefaultFolder( );     defaultPopFolder = defaultPopFolder.getFolder("INBOX");     defaultPopFolder.open(Folder.READ_ONLY);     Message[] msgs = defaultPopFolder.getMessages( );     if(msgs != null)       for (int i = 0; i < msgs.length; i++) {         // Display the message envelope         System.out.println("\n\r----------------------------------");         System.out.println("Subject: " + msgs[i].getSubject( ));         Address[] from = msgs[i].getFrom( );         if(from != null)           for(int a = 0; a < from.length; a++)             System.out.println("From: " + from[a]);         // Display the content         if (msgs[i].isMimeType("text/plain")) {           System.out.println((String)msgs[i].getContent( ));         } else if (msgs[i].isMimeType("multipart/*")) {           Multipart mp = (Multipart)msgs[i].getContent( );           int count = mp.getCount( );           for(int m = 0; m < count; m++) {             showBodyPart((MimeBodyPart)mp.getBodyPart(m));           }         } else if (msgs[i].isMimeType("message/rfc822")) {           System.out.println("Nested Message");         } else {           System.out.println(msgs[i].getContent( ).toString( ));         }       }// end for     } catch (MessagingException me) {       me.printStackTrace(System.out);     } catch (IOException ie) {       ie.printStackTrace(System.out);     }   } // End main( )   // Show or save a MIME body part; very simple   public static void showBodyPart(MimeBodyPart p) {     try {       String contentType = p.getContentType( );       System.out.println("-- MIME Part: " + contentType);       if(contentType.startsWith("text/"))         System.out.println((String)p.getContent( ));       else if(p.getFileName( ) != null) {         File f = new File(p.getFileName( ));         FileOutputStream fos = new FileOutputStream(f);         byte[] b = new byte[1024];         InputStream is = p.getInputStream( );         fos.write(b);         is.close( );         fos.close( );         System.out.println("Attachment saved as " + f.getAbsolutePath( ));       } else {         System.out.println(         "Cannot display this content type and no filename supplied.");       }     } catch(Exception e) {       System.out.println("Exception Caught: " + e.getMessage( ));     }   } // End showBodyPart( ) } // End class 

15.4.2. Sending Multipart Messages

Creating a multipart message isn't any more complex than creating a regular MIME message. First, instantiate a MimeMultipart object, which will serve as a container for the various parts of the message. For each part, create a MimeBodyPart and set its content via the setContent( ) method. Add each body part to the MimeMultipart object using the addBodyPart( ) method. Finally, add the Multipart object as the content of a MimeMessage, and send that message normally.

There are, of course, a few wrinkles in the process, particularly when dealing with file attachments. To attach a file to a message, you need to specify the filename when creating the MimeBodyPart (via the setFileName( ) method) and provide the actual file data. Note that the content is provided via the JavaBeans Activation Framework's DataHandler object, which we discussed earlier in this chapter. DataHandler objects can be fed via DataSource objects. JAF provides two of these: FileDataSource and URLDataSource, which are more or less as advertisedone retrieves data from a file, the other from a URL. In addition to retrieving raw bytes, the DataSource will also provide the DataHandler with an appropriate content type. Here's how:

     File f = new File("foo.jpg");     MimeBodyPart mbp = new MimeBodyPart( );     mbp.setFileName(f.getName( ));     mbp.setDataHandler(new DataHandler(new FileDataSource(f))); 

Example 15-5 puts the pieces together. It sends an email to root@company.com from logs@company.com, with a brief text message and a file attachment containing /var/logs/today.log.

Example 15-5. Sending a multipart message
 import javax.mail.*; import javax.mail.internet.*; import javax.activation.*; import java.io.File; import java.util.Properties; public class MimeAttach {   public static void main(String[] args) {     try {       Properties props = System.getProperties( );       props.put("mail.smtp.host", "mail.company.com");       Session session = Session.getDefaultInstance(props, null);       Message msg = new MimeMessage(session);       msg.setFrom(new InternetAddress("logs@company.com"));       msg.setRecipient(Message.RecipientType.TO,                        new InternetAddress("root@company.com"));       msg.setSubject("Today's Logs");       Multipart mp = new MimeMultipart( );       MimeBodyPart mbp1 = new MimeBodyPart( );       mbp1.setContent("Log file for today is attached.", "text/plain");       mp.addBodyPart(mbp1);       File f = new File("/var/logs/today.log");       MimeBodyPart mbp = new MimeBodyPart( );       mbp.setFileName(f.getName( ));       mbp.setDataHandler(new DataHandler(new FileDataSource(f)));       mp.addBodyPart(mbp);       msg.setContent(mp);       Transport.send(msg);     } catch (MessagingException me) {       me.printStackTrace( );     }   } } 

JavaMail's support for multipart messages opens up some interesting possibilities for using email within your enterprise applications. With a few POP or IMAP mailboxes, you can write software that will exchange messages without any user intervention. This can be used to synchronize configuration files, exchange XML documents, or even handle more mundane tasks such as generating automated status emails.



Java Enterprise in a Nutshell
Java Enterprise in a Nutshell (In a Nutshell (OReilly))
ISBN: 0596101422
EAN: 2147483647
Year: 2004
Pages: 269

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