Search Results for 'mail'

ATOM Icon

1 POSTS

  1. 2007/09/11 JavaMail by freesens.com

JavaMail

원본 : http://www.vipan.com/htdocs/javamail.html


Home: www.vipan.com Vipan Singla e-mail: vipan@vipan.com
E-Mailing Through Java

JavaMail

  • You can send or fetch e-mail through your Java application or servlet using the JavaMail API.
  • You use the JavaMail API where as JavaMail implementation providers implement the JavaMail API to give you a JavaMail client (Java JAR file). Sun gives you mail.jar which has Sun's SMTP, POP3 and IMAP client implementations along with the JavaMail API. This is sufficient to send and receive e-mail but not to read or post to newgroups which use NNTP.

Sample Code to Send E-Mail

  • To compile and run, you must have mail.jar (from the JavaMail download) and activation.jar (from the JavaBeans Activation Framework download) in Java classpath.
  • You need to replace email addresses and mail server with your values where noted. Username and password is generally not needed to send e-mail although your ISP may still require it to prevent spam from going through its systems.
  • This sample code has debugging turned on ("mail.debug") to see what is going on behind the scenes in JavaMail code.
    import java.util.*;
    import javax.mail.*;
    import javax.mail.internet.*;
    import javax.activation.*;
    
    // Send a simple, single part, text/plain e-mail
    public class TestEmail {
    
        public static void main(String[] args) {
    
            // SUBSTITUTE YOUR EMAIL ADDRESSES HERE!!!
            String to = "vipan@vipan.com";
            String from = "vipan@vipan.com";
            // SUBSTITUTE YOUR ISP'S MAIL SERVER HERE!!!
            String host = "smtp.yourisp.net";
    
            // Create properties, get Session
            Properties props = new Properties();
    
            // If using static Transport.send(),
            // need to specify which host to send it to
            props.put("mail.smtp.host", host);
            // To see what is going on behind the scene
            props.put("mail.debug", "true");
            Session session = Session.getInstance(props);
    
            try {
                // Instantiatee a message
                Message msg = new MimeMessage(session);
    
                //Set message attributes
                msg.setFrom(new InternetAddress(from));
                InternetAddress[] address = {new InternetAddress(to)};
                msg.setRecipients(Message.RecipientType.TO, address);
                msg.setSubject("Test E-Mail through Java");
                msg.setSentDate(new Date());
    
                // Set message content
                msg.setText("This is a test of sending a " +
                            "plain text e-mail through Java.\n" +
                            "Here is line 2.");
    
                //Send the message
                Transport.send(msg);
            }
            catch (MessagingException mex) {
                // Prints all nested (chained) exceptions as well
                mex.printStackTrace();
            }
        }
    }//End of class

Sample Code to Send Multipart E-Mail, HTML E-Mail and File Attachments

  • To compile and run, you must have mail.jar (from the JavaMail download) and activation.jar (from the JavaBeans Activation Framework download) in Java classpath.
  • You need to replace email addresses and mail server with your values where noted.
  • This sample code has debugging turned on ("mail.debug") to see what is going on behind the scenes in JavaMail code.
    import java.util.*;
    import java.io.*;
    import javax.mail.*;
    import javax.mail.internet.*;
    import javax.activation.*;
    
    public class SendMailUsage {
    
        public static void main(String[] args) {
    
            // SUBSTITUTE YOUR EMAIL ADDRESSES HERE!!!
            String to = "you@yourisp.net";
            String from = "you@yourisp.net";
            // SUBSTITUTE YOUR ISP'S MAIL SERVER HERE!!!
            String host = "smtpserver.yourisp.net";
    
            // Create properties for the Session
            Properties props = new Properties();
    
            // If using static Transport.send(),
            // need to specify the mail server here
            props.put("mail.smtp.host", host);
            // To see what is going on behind the scene
            props.put("mail.debug", "true");
    
            // Get a session
            Session session = Session.getInstance(props);
    
            try {
                // Get a Transport object to send e-mail
                Transport bus = session.getTransport("smtp");
    
                // Connect only once here
                // Transport.send() disconnects after each send
                // Usually, no username and password is required for SMTP
                bus.connect();
                //bus.connect("smtpserver.yourisp.net", "username", "password");
    
                // Instantiate a message
                Message msg = new MimeMessage(session);
    
                // Set message attributes
                msg.setFrom(new InternetAddress(from));
                InternetAddress[] address = {new InternetAddress(to)};
                msg.setRecipients(Message.RecipientType.TO, address);
                // Parse a comma-separated list of email addresses. Be strict.
                msg.setRecipients(Message.RecipientType.CC,
                                    InternetAddress.parse(to, true));
                // Parse comma/space-separated list. Cut some slack.
                msg.setRecipients(Message.RecipientType.BCC,
                                    InternetAddress.parse(to, false));
    
                msg.setSubject("Test E-Mail through Java");
                msg.setSentDate(new Date());
    
                // Set message content and send
                setTextContent(msg);
                msg.saveChanges();
                bus.sendMessage(msg, address);
    
                setMultipartContent(msg);
                msg.saveChanges();
                bus.sendMessage(msg, address);
    
                setFileAsAttachment(msg, "C:/WINDOWS/CLOUD.GIF");
                msg.saveChanges();
                bus.sendMessage(msg, address);
    
                setHTMLContent(msg);
                msg.saveChanges();
                bus.sendMessage(msg, address);
    
                bus.close();
    
            }
            catch (MessagingException mex) {
                // Prints all nested (chained) exceptions as well
                mex.printStackTrace();
                // How to access nested exceptions
                while (mex.getNextException() != null) {
                    // Get next exception in chain
                    Exception ex = mex.getNextException();
                    ex.printStackTrace();
                    if (!(ex instanceof MessagingException)) break;
                    else mex = (MessagingException)ex;
                }
            }
        }
    
    
    
        // A simple, single-part text/plain e-mail.
        public static void setTextContent(Message msg) throws MessagingException {
                // Set message content
                String mytxt = "This is a test of sending a " +
                                "plain text e-mail through Java.\n" +
                                "Here is line 2.";
                msg.setText(mytxt);
    
                // Alternate form
                msg.setContent(mytxt, "text/plain");
    
        }
    
    
    
        // A simple multipart/mixed e-mail. Both body parts are text/plain.
        public static void setMultipartContent(Message msg) throws MessagingException {
            // Create and fill first part
            MimeBodyPart p1 = new MimeBodyPart();
            p1.setText("This is part one of a test multipart e-mail.");
    
            // Create and fill second part
            MimeBodyPart p2 = new MimeBodyPart();
            // Here is how to set a charset on textual content
            p2.setText("This is the second part", "us-ascii");
    
            // Create the Multipart.  Add BodyParts to it.
            Multipart mp = new MimeMultipart();
            mp.addBodyPart(p1);
            mp.addBodyPart(p2);
    
            // Set Multipart as the message's content
            msg.setContent(mp);
        }
    
    
    
        // Set a file as an attachment.  Uses JAF FileDataSource.
        public static void setFileAsAttachment(Message msg, String filename)
                 throws MessagingException {
    
            // Create and fill first part
            MimeBodyPart p1 = new MimeBodyPart();
            p1.setText("This is part one of a test multipart e-mail." +
                        "The second part is file as an attachment");
    
            // Create second part
            MimeBodyPart p2 = new MimeBodyPart();
    
            // Put a file in the second part
            FileDataSource fds = new FileDataSource(filename);
            p2.setDataHandler(new DataHandler(fds));
            p2.setFileName(fds.getName());
    
            // Create the Multipart.  Add BodyParts to it.
            Multipart mp = new MimeMultipart();
            mp.addBodyPart(p1);
            mp.addBodyPart(p2);
    
            // Set Multipart as the message's content
            msg.setContent(mp);
        }
    
    
    
        // Set a single part html content.
        // Sending data of any type is similar.
        public static void setHTMLContent(Message msg) throws MessagingException {
    
            String html = "<html><head><title>" +
                            msg.getSubject() +
                            "</title></head><body><h1>" +
                            msg.getSubject() +
                            "</h1><p>This is a test of sending an HTML e-mail" +
                            " through Java.</body></html>";
    
            // HTMLDataSource is an inner class
            msg.setDataHandler(new DataHandler(new HTMLDataSource(html)));
        }
    
    
    
        /*
         * Inner class to act as a JAF datasource to send HTML e-mail content
         */
        static class HTMLDataSource implements DataSource {
            private String html;
    
            public HTMLDataSource(String htmlString) {
                html = htmlString;
            }
    
            // Return html string in an InputStream.
            // A new stream must be returned each time.
            public InputStream getInputStream() throws IOException {
                if (html == null) throw new IOException("Null HTML");
                return new ByteArrayInputStream(html.getBytes());
            }
    
            public OutputStream getOutputStream() throws IOException {
                throw new IOException("This DataHandler cannot write HTML");
            }
    
            public String getContentType() {
                return "text/html";
            }
    
            public String getName() {
                return "JAF text/html dataSource to send e-mail only";
            }
        }
    
    } //End of class

Sample Code to Fetch E-Mail

  • To compile and run, you must have mail.jar (from the JavaMail download) and activation.jar (from the JavaBeans Activation Framework download) in Java classpath.
  • You need to replace mail server, username and password with your values where noted.
  • This sample code has debugging turned on ("mail.debug") to see what is going on behind the scenes in JavaMail code.
    import java.util.*;
    import java.io.*;
    import javax.mail.*;
    import javax.mail.internet.*;
    import javax.mail.search.*;
    import javax.activation.*;
    
    
    public class FetchMailUsage {
    
        public static void main(String[] args) {
    
            // SUBSTITUTE YOUR ISP's POP3 SERVER HERE!!!
            String host = "pop.yourisp.net";
            // SUBSTITUTE YOUR USERNAME AND PASSWORD TO ACCESS E-MAIL HERE!!!
            String user = "your_username";
            String password = "your_password";
            // SUBSTITUTE YOUR SUBJECT SUBSTRING TO SEARCH HERE!!!
            String subjectSubstringToSearch = "Test E-Mail through Java";
    
            // Get a session.  Use a blank Properties object.
            Session session = Session.getInstance(new Properties());
    
            try {
    
                // Get a Store object
                Store store = session.getStore("pop3");
                store.connect(host, user, password);
    
                // Get "INBOX"
                Folder fldr = store.getFolder("INBOX");
                fldr.open(Folder.READ_WRITE);
                int count = fldr.getMessageCount();
                System.out.println(count  + " total messages");
    
                // Message numebers start at 1
                for(int i = 1; i <= count; i++) {
    								// Get  a message by its sequence number
                    Message m = fldr.getMessage(i);
    
                    // Get some headers
                    Date date = m.getSentDate();
                    Address [] from = m.getFrom();
                    String subj = m.getSubject();
                    String mimeType = m.getContentType();
                    System.out.println(date + "\t" + from[0] + "\t" +
                                        subj + "\t" + mimeType);
                }
    
                // Search for e-mails by some subject substring
                String pattern = subjectSubstringToSearch;
                SubjectTerm st = new SubjectTerm(pattern);
                // Get some message references
                Message [] found = fldr.search(st);
    
                System.out.println(found.length +
                                    " messages matched Subject pattern \"" +
                                    pattern + "\"");
    
                for (int i = 0; i < found.length; i++) {
                    Message m = found[i];
                    // Get some headers
                    Date date = m.getSentDate();
                    Address [] from = m.getFrom();
                    String subj = m.getSubject();
                    String mimeType = m.getContentType();
                    System.out.println(date + "\t" + from[0] + "\t" +
                                        subj + "\t" + mimeType);
    
                    Object o = m.getContent();
                    if (o instanceof String) {
                        System.out.println("**This is a String Message**");
                        System.out.println((String)o);
                    }
                    else if (o instanceof Multipart) {
                        System.out.print("**This is a Multipart Message.  ");
                        Multipart mp = (Multipart)o;
                        int count3 = mp.getCount();
                        System.out.println("It has " + count3 +
                            " BodyParts in it**");
                        for (int j = 0; j < count3; j++) {
                            // Part are numbered starting at 0
                            BodyPart b = mp.getBodyPart(j);
                            String mimeType2 = b.getContentType();
                            System.out.println( "BodyPart " + (j + 1) +
                                                " is of MimeType " + mimeType);
    
                            Object o2 = b.getContent();
                            if (o2 instanceof String) {
                                System.out.println("**This is a String BodyPart**");
                                System.out.println((String)o2);
                            }
                            else if (o2 instanceof Multipart) {
                                System.out.print(
                                    "**This BodyPart is a nested Multipart.  ");
                                Multipart mp2 = (Multipart)o2;
                                int count2 = mp2.getCount();
                                System.out.println("It has " + count2 +
                                    "further BodyParts in it**");
                            }
                            else if (o2 instanceof InputStream) {
                                System.out.println(
                                    "**This is an InputStream BodyPart**");
                            }
                        } //End of for
                    }
                    else if (o instanceof InputStream) {
                        System.out.println("**This is an InputStream message**");
                        InputStream is = (InputStream)o;
                        // Assumes character content (not binary images)
                        int c;
                        while ((c = is.read()) != -1) {
                            System.out.write(c);
                        }
                    }
    
                    // Uncomment to set "delete" flag on the message
                    //m.setFlag(Flags.Flag.DELETED,true);
    
                } //End of for
    
                // "true" actually deletes flagged messages from folder
                fldr.close(true);
                store.close();
    
            }
            catch (MessagingException mex) {
                // Prints all nested (chained) exceptions as well
                mex.printStackTrace();
            }
            catch (IOException ioex) {
                ioex.printStackTrace();
            }
    
        }
    
    
    } //End of class

Useful Classes and Interfaces

  • A Session object authenticates the user and controls access to the mail servers. The Session class is a final concrete class. It cannot be subclassed. By calling the appropriate factory method on a Session object, you can obtain Transport and Store objects which support specific protocols to send or fetch e-mail respectively.
  • You convert e-mail address strings such as "user@domain.com" into an InternetAddress object to use it with JavaMail. The InternetAddress class extends the abstract Address class to come up with an "rfc822" type address.
    public class InternetAddress extends Address implements Cloneable
     where:
     public abstract class Address extends Object implements Serializable
  • You construct an e-mail message as an object of the MimeMessage class.
    public class MimeMessage extends Message implements MimePart
      where
      public abstract class Message extends Object implements Part
      public interface MimePart extends Part
      public interface Part

    All Java e-mails are of Message type.

  • Each Message object has a content. The content can either be a multipart content or not.
  • A simple content is just some plain text, for example. There is no special class for simple (non-multipart) content. You just say msg.setText(textString).
  • MimeMultipart class handles multipart content which adheres to the MIME specifications.
    public class MimeMultipart extends Multipart
     where:
     public abstract class Multipart extends Object

    You create a new MimeMultipart object by invoking its default constructor.

    When you get content of an multipart e-mail, it always returns an object of this type.

  • MimeMultipart acts as a container for multiple parts to be sent in the e-mail. Each part is of type MimeBodyPart.
    public class MimeBodyPart extends BodyPart implements MimePart
      where:
      public abstract class BodyPart extends Object implements Part
      public interface Part

    MimeMultipart's getBodyPart(int index) method returns the MimeBodyPart object at the given index. Index starts at 0. The addBodyPart(...) method adds a new MimeBodyPart object to it as a step towards constructing a new multipart MimeMessage.

    Each Bodypart type object can contain either a JAF DataHandler object or another (nested) Multipart type object. So, check the content-type of each BodyPart before using it in your code.

    To extract a nested Multipart type object from a MimePart containing a ContentType attribute set to "multipart/*", use the MimePart's getContent() method. Its getSubType method returns the multipart message MIME subtype. The subtype defines the relationship among the individual body parts of a multipart message.

  • If the content of a Message object is an instance of the Multipart class, it means that you need to cast the content into a Multipart and look for BodyPart type objects within the resulting object to access each individual part.
  • Another Message object can not be contained directly in a Multipart object, it must be embedded in a BodyPart first.
  • Each Message or BodyPart type object also has some attributes.
  • A Message's attributes can be From, To, Subject, Reply-To etc. You can also add non-standard attributes as headers.
  • A BodyPart type object does not have attributes that set From, To, Subject, ReplyTo, or other address header fields.
  • Messages are stored in Folder objects which may also contain subfolders. All mail servers have the folder named "INBOX". The Folder class declares methods that fetch, append, copy and delete messages. A Folder object can also send events to components registered as event listeners.
    • "fldr.getType" returns whether a Folder can hold subfolders, messages, or both.
    • "store.getDefaultFolder" returns the root folder.
    • "fldr.list" returns all the subfolders under that folder.
    • "fldr.getFolder(folderName)" returns the named subfolder. This subfolder need not exist physically in the store.
    • "fldr.exists" indicates whether this folder exists.
    • "store.create" creates a folder
    • A closed Folder object allows deleting and renaming the folder, listing and creating subfolders, and monitoring for new messages.
    • "fldr.open" opens a Folder object (only if it can contain messages). You cannot call "open", "delete" and "renameTo" on an open folder.
  • Folders are stored in a database accessed by a Store class which requires username, and password to connect to the database. As a user, you will first connect to the mail server by calling one of the three connect(...) methods on a Store class, specifying the server to access, username and password.
  • Messages stored within a Folder object are sequentially numbered, starting at 1. Calling msg.getMessageNumber() returns its sequence number. You can reference a message either by its sequence number or by the corresponding Message object itself.

    When messages marked as deleted are actually purged, the remaining messages are renumbered. So there is no guarantee that a message will always have the same message number in a folder. Since a sequence number can change within a session, use references to Message objects rather than sequence numbers as cached references to messages.

  • Use FetchProfile to selectively retrieve message attributes/content for efficiency:
    Message[] msgs = folder.getMessages();
    
    FetchProfile fp = new FetchProfile();
    // ENVELOPE, CONTENT_INFO and/or FLAGS
    // ENVELOPE:  From, To, Cc, Bcc, ReplyTo, Subject and Date
    // CONTENT_INFO: Type, Disposition, Description, Size and LineCount
    // FLAGS: Flags set on this message
    fp.add(FetchProfile.Item.ENVELOPE);
    // Add a specific header field to the list of attributes to be prefetched
    fp.add("X-mailer");
    
    folder.fetch(msgs, fp);
    for (int i = 0; i < folder.getMessageCount(); i++) {
      display(msgs[i].getFrom());
      display(msgs[i].getSubject());
      display(msgs[i].getHeader("X-mailer"));
    }

Steps to Use JavaMail

  • First, get the Session object:
    Properties props = new Properties();
    // From system properties
    //Properties props = System.getProperties();
    
    // Get the shared Session object
    Session session = Session.getDefaultInstance(props);
    // Get an unshared Session object
    Session session = Session.getInstance(props);
    

    The "props" Properties file contains mail protocols to use, mail host and port to connect to, username etc. which will be used later to connect to the mail server. It can be blank although you may want to set mail.store.protocol, mail.transport.protocol, mail.host, mail.user and mail.from properties. Passwords can not be specified using properties. Here are the various properties that can be in the Properties object and what they do:

    • mail.store.protocol: Default protocol to fetch messages.
    • mail.transport.protocol: Default protocol to send messages.
    • mail.protocol.host: Protocol-specific default mail server such as mail.smtp.host=smtp2.yourisp.com. Defaults to what's in "mail.host" property (see next).
    • mail.host: Default mail server for both sending and receiving email.
    • mail.user: Mail server username. Defaults to the JVM system property user.name. The Store and Transport objects' connect() method uses this property to send the username to the mail server, if the protocol-specific username property is absent (see next).
    • mail.protocol.user: Protocol-specific default username for connecting to the mail server. Defaults to what's in "mail.user" property.
    • mail.from: Specifies the return address of the current user. Used by the InternetAddress.getLocalAddress method to specify the current user뭩 email address. Defaults to username@host.
    • mail.debug: If specified as "true" string, prints messages to System.out showing various protocol commands being issued behind the scenes. Default is "false". You can override it later with "Session.setDebug" method but then, debug messages will only be turned on from that point onwards and you will miss the session creation messages.
  • Sending E-Mail

    1. Instantiate a new message:
        Message msg = new MimeMessage(session);
    2. Set message's attributes:
        InternetAddress[] toAddrs = new InternetAddress[1];
        toAddrs[0] = new InternetAddress("your@buddy.com");
        Address fromAddr = new InternetAddress("you@home.com");
        msg.setFrom(fromAddr);
        msg.setRecipients(Message.RecipientType.TO, toAddrs);
        msg.setSubject("Test Email");
        msg.setSentDate(new Date());
        // Custom header other than pre-defined ones
        msg.setHeader("content-type", "text/plain");
    3. Set message's content:
        msg.setText("This is a test message");
        // Or, for other content types, e.g.
        msg.setContent("This is a test message", "text/plain");
      1. To create MIME multipart content, first instantiate a MimeMultipart object. The default subtype of a multipart content is "mixed". You can specify other subtypes such as "alternative", "related", "parallel" and "signed".
            Multipart mp = new MimeMultipart();
            // Some other subtype
            //Multipart mp = new MimeMultipart("alternative");
      2. Instantiate and set content of MimeBodyPart objects
            BodyPart b1 = new MimeBodyPart();
            b1.setContent("Spaceport Map","text/plain");
        
            BodyPart b2 = new MimeBodyPart();
            // Map is some binary postscript file
            b2.setContent(map,"application/postscript");
      3. Add BodyPart objects to Multipart object
            mp.addBodyPart(b1);
            mp.addBodyPart(b2);
      4. Finally, set the Multipart object as the message's content
            msg.setContent(mp); // This form takes a Multipart object
    4. Send the message
      • Automatic Procedure:
            Transport.send(msg);
            // Ignore recipient addresses in the Message object, specify your own
            Transport.send(msg, recipientAddressesArray);

        This is a convenience static method. It does not allow registering event listeners with the Transport object. Depending on each recipient's address type, it instantiates the appropriate Transport subclass, calls msg.saveChanges() and calls transportObject.sendMessage(msg).

      • Manual Procedure:
        1. Ensure that proper message headers are updated:
                msg.saveChanges();
        2. Get a Transport object specific to the send protocol (usually "smtp")
                // Use provider configuration file
                Transport bus = session.getTransport("smtp");
                // Use address type to protocol mapping file
                //Transport bus = session.getTransport(address);
                // Use session properties to get default protocol
                //Transport bus = session.getTransport();
        3. Register event listeners if you want:
                // Add a class implementing the appropriate listener interface
                bus.addConnectionListener(this); // this implements ConnectionListener
                bus.addTransportListener(this);  // this implements TransportListener
        4. Make recipient address array:
                Address [] addresses = msg.getAllRecipients();
                // Or, Make your own
                Address [] addresses = {
                                          new InternetAddress("you@me.com"),
                                          new InternetAddress("me@you.com"),
                                       };
        5. Send the message:
                bus.sendMessage(msg, addresses);
    5. Optionally, write the message out to a bytestream (may be to save as a draft on disk, for example):
        msg.writeTo(someOutputStream);
  • Fetching E-Mail

    1. Get the Store object:
        // Gets protocol from session properties
        Store store = session.getStore();
        // Store for a non-default protocol
        Store store = session.getStore("pop3");
    2. Connect to the store:
        //Uses session properties
        store.connect();
        //uses default port, hostString is like "mail.yourisp.com"
        store.connect(hostString, username, password);
        //uses specific port, -1 means default
        store.connect(hostString, portNumberInteger username, password);
    3. List folders in the store and list/view messages in a folder:
        // get the INBOX folder  (All stores usually have this one)
        Folder inbox = store.getFolder("INBOX");
        // open the INBOX folder
        inbox.open(Folder.READ_WRITE);
        Message m = inbox.getMessage(1); // get Message #1
    4. Get a message's attributes:
        // Get the subject attribute
        String subject = m.getSubject();
    5. Return the MIME type of a message's content:
        String mimeType = m.getContentType();
    6. Get a message's content:
        Object o = m.getContent();
    7. The type of the returned object depends on the type of the actual content.
      • A "text/plain" content usually returns a String object.
      • A "multipart/%lt;whatever here>" object always returns a Multipart object or its subclass.
      • For unknown content types, any mail-specific encodings are decoded and an InputStream object is returned.
          if (o instanceof String) {
            System.out.println("This is a String");
            System.out.println((String)o);
          }
          else if (o instanceof Multipart) {
            System.out.println("This is a Multipart");
            Multipart mp = (Multipart)o;
            int count = mp.getCount();
            for (int i = 0; i < count; i++) {
              BodyPart b = mp.getBodyPart(i);
              mp.removeBodyPart(b);
              // Or, simply
              //mp.removeBodyPart(i);
              mp.addBodyPart(b);
            }
          }
          else if (o instanceof InputStream) {
            System.out.println("This is just an input stream");
            InputStream is = (InputStream)o;
            int c;
            while ((c = is.read()) != -1) {
              System.out.write(c);
            }
          }
    8. When done, close all open folders and then, the store:
        inbox.close(); // Close the INBOX
        store.close(); // Close the Store

Utility Classes

  • You can use the MimeUtility class to convert non-US-ASCII headers and content to mail-safe format. Remember to do it before calling setHeader(), addHeader() and addHeaderLine() methods. In addition, these header fields must be folded (wrapped) before being sent if they exceed the line length limitation for the transport (1000 bytes for SMTP). Received headers may have been folded. Your application is responsible for folding and unfolding headers as appropriate.
  • All methods in MimeUtility utility class are static methods.
    • getEncoding() takes a JAF DataSource object and returns the Content-Transfer-Encoding that should be applied to the data in that DataSource object to make it mail-safe.
    • encode() wraps an encoder around the given output stream based on the specified Content-Transfer-Encoding.
    • decode() decodes the given input stream, based on the specified Content-Transfer-Encoding.
    • Since RFC 822 prohibits non US-ASCII characters in headers, you should first call MimeUtility.encodeText() method on the header names and values, and then call setHeader(), addHeader() or addHeaderLine() methods on the encoded strings. It encodes header values only if they contain non US-ASCII characters.
        MimePart part = ...
        String rawvalue = "FooBar Mailer, Japanese version 1.1"
        part.setHeader("X-mailer", MimeUtility.encodeText(rawvalue));
    • Similarly, call MimeUtility.decodeText method on header values obtained from a MimeMessage or MimeBodyPart using the "getHeader" set of methods. This method takes a header value, applies RFC 2047 decoding standards, and returns the decoded value as a Unicode String. You should always run header values through the decoder to be safe.
        MimePart part = ...
        String rawvalue = part.getHeader("X-mailer")[0]);
        String  value = null;
        if ((rawvalue != null) {
           value = MimeUtility.decodeText(rawvalue);
        }
  • The ContentType class is a utility class that can parse received MIME content-type headers and also generate new MIME content-type headers.
    Multipart part = ...;
    String type = part.getContentType();
    ContentType cType = new ContentType(type);
    if (cType.match("application/x-foobar")) {
      // Extract a MIME parameter
      iString color = cType.getParameter("color");
    }
    
    ContentType cType2 = new ContentType();
    cType2.setPrimaryType("application");
    cType2.setSubType("x-foobar");
    cType2.setParameter("color", "red");
    // Construct a MIME Content-Type value
    String contentType = cType2.toString();

Message Flags

  • If a folder supports the special USER flag, you can set arbitrary user-definable flags on any message belonging to this folder. Other flags are:
    • ANSWERED: Message has been answered.
    • DRAFT: Message is a draft.
    • FLAGGED: Mark a message as flagged.
    • RECENT: This message is newly arrived in this folder. This flag is set when the message is first delivered into the folder and cleared when the containing folder is closed. Clients cannot set this flag.
    • SEEN: Marks a message that has been opened. It gets set when the message contents are retrieved.
    • DELETED: Allows undoable message deletion. Setting this flag for a message marks it deleted but does not physically remove the message from its folder. The client calls the expunge method on a folder to remove all deleted messages in that folder.
  • Methods to operate on flags of a message
    // Get current flags set on a message
    Flags msgFlags = msg.getFlags();
    
    // Get all supported flags by this folder
    Flags allowedFlags = fldr.getPermanentFlags();
    
    // Check if a Flags object contains a flag
    allowedFlags.contains(flagToCheck);
    
    // Add a flag to a set of flags using a Flags.Flag object
    msgFlags.add(flagToAdd);
    
    // Set the flags on a message
    msg.setFlags(msgFlags, isToBeSet);

JavaMail Events

  • JavaMail uses JDK 1.1 type event-handling mechanism. You can register your class as listeners to subclasses of MailEvent class. The Transport, Store and Folder classes generate such events.
  • A Transport object generates ConnectionEvent and TransportEvent. If the transport object connects successfully, it will fire the ConnectionEvent with the type set to OPENED. If the connection times out or is closed, ConnectionEvent with type CLOSED is generated. The sendMessage method of a Transport object generates a TransportEvent which contains information about the method뭩 success or failure. The event object contains three arrays of address arrays: validSent[], validUnsent[] and invalid[]:
    1. MESSAGE_DELIVERED: Message sent to all recipients successfully. validSent[] contains all the addresses. validUnsent[] and invalid[] are null.
    2. MESSAGE_NOT_DELIVERED: When ValidSent[] is null, the message was not successfully sent to any recipients. validUnsent[] may have addresses that are valid. invalid[] may contain invalid addresses.
    3. MESSAGE_PARTIALLY_DELIVERED: Message was successfully sent to some recipients but not to all. ValidSent[] holds addresses of recipients to whom the message was sent. validUnsent[] holds valid addresses but the message wasn't sent to them. invalid[] holds invalid addresses.
  • A Store object generates ConnectionEvent (generated on a successful connection or close), StoreEvent (event.getMessageType method returns either ALERT or NOTICE), FolderEvent (upon creation, deletion or renaming of a Folder).
  • A Folder object generates ConnectionEvent (a Folder is opened or closed), FolderEvent (this folder creates, deletes or renames) and MessageCountEvent (message count has changed, expunged Message objects are in the event).

More on JavaMail's Internal Workings

  • JavaMail supports simultaneous multiple sessions and each session can access multiple message stores and transports. In a JVM, multiple applications can share the same default mail session. This way, only one application needs to have the information and code necessary to connect to a mail server and authenticate the user. Other applications then simply call send or fetch methods.
  • Session object's getInstance(...), getDefaultInstance(...), getStore(...) and getTransport(...) methods look for your configured javaMail implementations in two text files named javamail.providers and javamail.default.providers.

    Usually, you don't need to do anything because the default providers in mail.jar file are sufficient.

  • The lines in these files specify which Java class to use for which protocol. Sample javamail.providers file:
    protocol=imap; type=store; class=com.sun.mail.imap.IMAPStore; vendor=SunMicrosystems,Inc;
    protocol=smtp; type=transport;class=com.sun.mail.smtp.SMTPTransport;
  • It searches for configured implementations as follows:
    1. First, using the java.home system property, it looks for the wanted protocol's configuration in the java.home/lib/javamail.providers file. There can be one such file per JVM.
    2. If the above file does not exist or the wanted protocol is not found in the above file, it looks for the wanted protocol's configuration in the META-INF/javamail.providers file in your application's directory or JAR file. There can be one such file per application.
    3. If the above file does not exist or the wanted protocol is not found in the above file, it looks for the wanted protocol's configuration in the META-INF/javamail.default.providers file in JavaMail's mail.jar file. There can be one such file per JavaMail installation.
  • For a specific protocol, the first provider listed wins and is used by default. You can change the default by setting the mail.protocol.class property to the class name you want when you create the Session object.
    props.put("mail.smtp.class", "com.acme.SMTPTRANSPORT");
    Session session = Session.getInstance(props, null);

    Or, you can change it later using Session's getProviders(), getProvider() and setProvider() methods.

    // Find out which implementations are available
    Provider[] providers = session.getProviders();
    // Pick a provider
    Provider yourPick = providers[5]; // For example
    // Then, set a provider
    session.setProvider(yourPick);
    

    A Provider object cannot be explicitly created; it must be retrieved using the session.getProviders() method and it must be one of those configured in the resource files.

    The providers in your files are added before the ones that come in mail.jar's default files. All are available from your code via the session.getProviders() method.

  • JavaMail can instantiate the correct Transport object implementing the correct protocol based on the recipient's address. How does it do that? It looks for address-type-to-protocol mapping in two text files named javamail.address.map and javamail.default.address.map.

    Usually, you don't need to do anything because the default mappings in mail.jar file are sufficient.

  • Each line of these files maps an address type to a transport protocol. To determine an address type, use javax.mail.Address.getType() method to get the address type. For example,
    Address a = new InternetAddress("your@buddy.com");
    String addrType = a.getType(); // Returns "rfc822"

    Two common address types are "rfc822" (InternetAddress class) and "news" (NewsAddress class).

  • Sample javamail.address.map:
    rfc822=smtp
    news=nntp
  • It searches for configured mappings as follows (This is the same search order as for the providers file above):
    1. First, using the java.home system property, it looks for the wanted address type's mapping in the java.home/lib/javamail.address.map file. There can be one such file per JVM.
    2. If the above file does not exist or the wanted address type is not found in the above file, it looks for the wanted address type's mapping in the META-INF/javamail.address.map file in your application's directory or JAR file. There can be one such file per application.
    3. If the above file does not exist or the wanted address type is not found in the above file, it looks for the wanted address type's mapping in the META-INF/javamail.default.address.map file in JavaMail's mail.jar file. There can be one such file per JavaMail installation.
  • Folders can also be accessed using URLNames which may be constructed from strings specifying protocol, host, port, file, username, password. RFC 1738 specifies the URL syntax for IP-based protocols such as IMAP4 and POP3. Specify -1 as port number to use the default port.
    // Get a Store using the "scheme" part of the URL string
    Store s = session.getStore(URLName);
    // Or, directly
    // First gets a Store which uses the rest of URLName
    // to locate and instantiate Folder
    Folder f = session.getFolder(URLName);
  • Proper ways to expunge a folder:
    1. Expunge the folder, close it. Reopen and refetch messages from that Folder.
    2. Issue the "close" method with the "expunge" parameter set to "true".
  • You can search a folder (and, recursively, the entire store database) for the messages you are looking for. The abstract SearchTerm class represents search terms. It has a single method: public boolean match(Message msg); There are concrete subclasses of this class to search on subject, from, to etc. and to specify AND and OR criteria.

    The Folder class supports searches on messages:

    public Message[] search(SearchTerm term)
    public Message[] search(SearchTerm term, Message[] msgs)
  • The content of a message is a collection of bytes. There is no built-in knowledge in JavaMail of the data type or format of the message content. Instead, the "Message" class object interacts with its own content through an intermediate layer - the JavaBeans Activation Framework (JAF). So, JavaMail uses JAF to handle access to data based on data-type. The out-of-the-box JAF provides two very simple JAF-aware viewer beans: Text Viewer and Image Viewer. These beans handle data where content-type has been set to text/plain or image/gif. JavaMail implementation providers (not you) need to write additional viewers that support some of the basic content types seen on the Internet such as text/html, multipart/mixed and message/rfc822.

How E-Mail Works

  • The first e-mail message with an "@" sign in the address was sent in 1971.
  • An e-mail system consists of two different servers running on a server machine. You connect to the SMTP (Simple Mail Transfer Protocol) server on its well-known port number 25 to send e-mail to others. And, you connect to the POP3 (Post Office Protocol version 3) server on its well-known port number 110 to fetch the e-mail you may have received.
  • The email program on your computer interacts with the two mail servers at your ISP (Internet Service Provider) to send and fetch email. The interaction is dead simple. You compose your email and submit it to your e-mail program. Your email program connects over the Internet to the mail server, asks you for a username and password (if necessary), and supplies that to the mail server to authenticate you. After successful authentication, your e-mail program's interaction with an SMTP server goes something like this (from HowStuffWorks.com):

    Your e-mail program:helo test
    Mail server:250 mx1.mindspring.com Hello abc.sample.com
    [220.57.69.37], pleased to meet you

    Your e-mail program:mail from: test@sample.com
    Mail server:250 2.1.0 test@sample.com... Sender ok
    Your e-mail program:rcpt to: jsmith@mindspring.com
    Mail server:250 2.1.5 jsmith... Recip

크리에이티브 커먼즈 라이센스
Creative Commons License
이올린에 북마크하기

Posted by freesens.com

2007/09/11 11:04 2007/09/11 11:04
,
Response
No Trackback , No Comment
RSS :
http://blog.freesens.com/freesens/rss/response/147


블로그 이미지

- freesens.com

TC-Cumulus by reznoa requires Flash Player 9 or better.

Notices

Archives

Calendar

«   2012/02   »
      1 2 3 4
5 6 7 8 9 10 11
12 13 14 15 16 17 18
19 20 21 22 23 24 25
26 27 28 29      

Site Stats

Total hits:
319203
Today:
41
Yesterday:
51