| Home: www.vipan.com | Vipan Singla | e-mail: vipan@vipan.com |
JavaMail
|
Sample Code to Send E-Mail
- To compile and run, you must have
mail.jar(from the JavaMail download) andactivation.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) andactivation.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) andactivation.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
Sessionobject 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
InternetAddressobject to use it with JavaMail. The InternetAddress class extends the abstractAddressclass 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
MimeMessageclass.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
Messagetype. - 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). MimeMultipartclass handles multipart content which adheres to the MIME specifications.public class MimeMultipart extends Multipart where: public abstract class Multipart extends ObjectYou 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 PartMimeMultipart's
getBodyPart(int index)method returns the MimeBodyPart object at the given index. Index starts at 0. TheaddBodyPart(...)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
DataHandlerobject 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. ItsgetSubTypemethod 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
Folderobjects 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
Storeclass 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 threeconnect(...)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
FetchProfileto 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.userandmail.fromproperties. 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.getLocalAddressmethod to specify the current user뭩 email address. Defaults tousername@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
- Instantiate a new message:
Message msg = new MimeMessage(session);
- 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"); - 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");- To create MIME multipart content, first instantiate a
MimeMultipartobject. 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"); - Instantiate and set content of
MimeBodyPartobjectsBodyPart b1 = new MimeBodyPart(); b1.setContent("Spaceport Map","text/plain"); BodyPart b2 = new MimeBodyPart(); // Map is some binary postscript file b2.setContent(map,"application/postscript"); - Add
BodyPartobjects toMultipartobjectmp.addBodyPart(b1); mp.addBodyPart(b2); - Finally, set the
Multipartobject as the message's contentmsg.setContent(mp); // This form takes a Multipart object
- To create MIME multipart content, first instantiate a
- 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 callstransportObject.sendMessage(msg). - Manual Procedure:
- Ensure that proper message headers are updated:
msg.saveChanges();
- 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(); - 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 - Make recipient address array:
Address [] addresses = msg.getAllRecipients(); // Or, Make your own Address [] addresses = { new InternetAddress("you@me.com"), new InternetAddress("me@you.com"), }; - Send the message:
bus.sendMessage(msg, addresses);
- Ensure that proper message headers are updated:
- Automatic Procedure:
- Optionally, write the message out to a bytestream (may be to save as a draft on disk, for example):
msg.writeTo(someOutputStream);
- Instantiate a new message:
-
Fetching E-Mail
- Get the Store object:
// Gets protocol from session properties Store store = session.getStore(); // Store for a non-default protocol Store store = session.getStore("pop3"); - 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); - 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 - Get a message's attributes:
// Get the subject attribute String subject = m.getSubject();
- Return the MIME type of a message's content:
String mimeType = m.getContentType();
- Get a message's content:
Object o = m.getContent(); - 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
Multipartobject or its subclass. - For unknown content types, any mail-specific encodings are decoded and an
InputStreamobject 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); } } - When done, close all open folders and then, the store:
inbox.close(); // Close the INBOX store.close(); // Close the Store
- Get the Store object:
Utility Classes
- You can use the
MimeUtilityclass to convert non-US-ASCII headers and content to mail-safe format. Remember to do it before callingsetHeader(), addHeader()andaddHeaderLine()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
MimeUtilityutility 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 callsetHeader(), addHeader()oraddHeaderLine()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.decodeTextmethod 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
ContentTypeclass 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
USERflag, 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
MailEventclass. The Transport, Store and Folder classes generate such events. - A Transport object generates
ConnectionEventandTransportEvent. If the transport object connects successfully, it will fire the ConnectionEvent with the type set toOPENED. If the connection times out or is closed, ConnectionEvent with typeCLOSEDis 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[]:MESSAGE_DELIVERED: Message sent to all recipients successfully. validSent[] contains all the addresses. validUnsent[] and invalid[] are null.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.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.getMessageTypemethod returns eitherALERTorNOTICE),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) andMessageCountEvent(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(...)andgetTransport(...)methods look for your configured javaMail implementations in two text files namedjavamail.providersandjavamail.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:
- First, using the java.home system property, it looks for the wanted protocol's configuration in the
java.home/lib/javamail.providersfile. There can be one such file per JVM. - 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.providersfile in your application's directory or JAR file. There can be one such file per application. - 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.providersfile in JavaMail'smail.jarfile. There can be one such file per JavaMail installation.
- First, using the java.home system property, it looks for the wanted protocol's configuration in the
- For a specific protocol, the first provider listed wins and is used by default. You can change the default by setting the
mail.protocol.classproperty 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.mapandjavamail.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):
- First, using the java.home system property, it looks for the wanted address type's mapping in the
java.home/lib/javamail.address.mapfile. There can be one such file per JVM. - 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.mapfile in your application's directory or JAR file. There can be one such file per application. - 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.mapfile in JavaMail'smail.jarfile. There can be one such file per JavaMail installation.
- First, using the java.home system property, it looks for the wanted address type's mapping in the
- Folders can also be accessed using
URLNameswhich 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:
- Expunge the folder, close it. Reopen and refetch messages from that Folder.
- 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
SearchTermclass 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
Posted by freesens.com



