Recently I wrote a java daemon process that monitors a POP3 email box for messages, automatically downloads the messages, and then processes them. Basically my daemon process looks for returned and bounced emails in a POP3 mailbox and then updates certain flags in our ERP system so we don't send to that email address again. In some cases people reply to the messages our ERP system sends out, and in that case my daemon process forwards those messages to an appropriate user for manual review and handling.
I’m not going to go into the details of how this daemon process work since it goes far beyond the scope of this post (and it is a huge piece of software in itself). However, I am going to share the basic java class that I use to check the POP3 mail account, download messages, and then loop through them for processing.
For this example to work, you will need to download the JavaBeans Activation Framework, and the Javamail libraries. Unzip the downloaded archives and put the appropriate jar file into your classpath. This example was tested with JavaMail 1.3.1 (mail-1.3.1.jar) and the Javabeans Activation Framework 1.0.2 (activation-1.0.2.jar).
My example also uses Log4j to log its output. If you don’t want to configure log4j, then replace all of my log.info and log.debug calls with a call to System.out.println.
Once you get your classpath setup, take the class I present below and compile it. The only thing you’ll have to modify to run the example is a few lines in the main() method. Once you get that running, you should be able to take the code, pick it apart, and make it do what you need for your own applications.
package com.tima.edelivery.util;
import java.util.*;
import java.net.*;
import java.io.*;
import javax.mail.*;
import javax.mail.Flags.*;
import javax.mail.internet.*;
import javax.activation.*;
import org.apache.log4j.*;
/**
* Utility class used for logging into a pop3 server account
* and processing messages in it. You can retrieve the unread message count,
* message details, delete the messages, etc.
*
* @author Tim Archer 09/30/2003
* @version $Revision: 1.1 $
*/
public class POP3 {
static Logger log = Logger.getLogger(POP3.class);
/**The URL of the POP3 server to connect to. This is set in the constructor
* to the value: "pop3://"+username+":"+password+"@"+hostname; */
protected String url = "";
/**The hostname of the POP3 server to connect to. */
protected String hostname = "";
/**The username to connect to the POP3 server with. */
protected String username = "";
/**The password to connect to the POP3 server with. */
protected String password = "";
/** The message store. */
protected Store store = null;
/** The Folder representing the users inbox. */
protected Folder inboxFolder = null;
/**
* Constructor.
*
* @param p_hostname the hostname of the pop3 server to connect to
* @param p_username the username to login to the pop3 account as
* @param p_password the password to use when logging into the pop3 account
* @throws Exception If an error occurs.
*
*/
public POP3 (String p_hostname, String p_username, String p_password) throws Exception {
hostname = p_hostname;
username = p_username;
password = p_password;
// url is formatted as
url = "pop3://"+username+":"+password+"@"+hostname;
}
/**
* Connect to the pop3 server.
*
* @throws Exception If an error occurs.
*/
public void connect () throws Exception {
boolean debug = false;
// Get a Properties object
Properties props = System.getProperties();
// Get a Session object
Session session = Session.getDefaultInstance(props, null);
session.setDebug(debug);
// Get a Store object
try {
URLName urln = new URLName(url);
store = session.getStore(urln);
store.connect();
} catch (Exception e) {
throw new Exception ("Unable to connect to POP3 server. "+e.toString());
}
try {
// Open the Folder
inboxFolder = store.getDefaultFolder();
if (inboxFolder == null) {
throw new Exception ("No default inbox folder found.");
}
inboxFolder = inboxFolder.getFolder("INBOX");
if (inboxFolder == null) {
throw new Exception ("INBOX folder does not exist.");
}
inboxFolder.open(Folder.READ_WRITE);
} catch (Exception e) {
throw new Exception ("Unable to open folder. "+e.toString());
}
}
/**
* Disconnect from the pop3 server.
*
* @throws Exception If an error occurs.
*/
public void disconnect () throws Exception {
try {
inboxFolder.close(true);
} catch (Exception e) {
throw new Exception ("Unable to close the POP3 Folder. "+e.toString());
}
try {
store.close();
} catch (Exception e) {
throw new Exception ("Unable to disconnect from POP3 server. "+e.toString());
}
}
/**
* Returns the number of messages in the users inbox.
* @return int The number of messages in the users inbox.
* @throws Exception If an error occurs.
*
*/
public int getMessageCount() throws Exception {
return inboxFolder.getMessageCount();
}
/**
* Returns the number of unread messages in the users folder.
* @return int The number of unread messages in the users folder.
* @throws Exception If an error occurs.
*
*/
public int getUnreadMessageCount() throws Exception {
return inboxFolder.getUnreadMessageCount();
}
/**
* Returns the number of new messages in the users folder.
* @return int The number of new messages in the users folder.
* @throws Exception If an error occurs.
*
*/
public int getNewMessageCount() throws Exception {
return inboxFolder.getNewMessageCount();
}
/**
* Get the Message object corresponding to the given message number.
* @param msgnum The index/message number of the message to get.
* @return Message The message at the specified index.
* @throws Exception If an error occurs.
*
*/
public Message getMessage(int msgnum) throws Exception{
return inboxFolder.getMessage(msgnum);
}
/**
* Get all Message objects from this Folder.
* @return Message[] The array of messages.
* @throws Exception If an error occurs.
*
*/
public Message[] getMessages() throws Exception{
return inboxFolder.getMessages();
}
/**
* Get the Message objects for message numbers specified in the array.
* @param msgnums An integer array containing the index/message
* number of the messages to get.
* @return Message[] The array of messages.
* @throws Exception If an error occurs.
*
*/
public Message[] getMessages(int[] msgnums) throws Exception {
return inboxFolder.getMessages(msgnums);
}
/**
* Get the Message objects for message numbers ranging from start through
* end, both start and end index inclusive.
* @param start The index/message number to start getting messages at.
* @param end The index/message number to stop getting messages at.
* @return Message[] The array of messages.
* @throws Exception If an error occurs.
*
*/
public Message[] getMessages(int start, int end) throws Exception{
return inboxFolder.getMessages(start, end);
}
/**
* Main unit test program.
* @param args Command line arguments.
*
*/
public static void main(String args[]) {
log.debug("TestPOP3 Starting");
try {
POP3 pop3 = new POP3("192.168.1.50", "tima", "mypassword");
pop3.connect();
log.info("Message Count:"+pop3.getMessageCount());
log.info("Unread Message Count:"+pop3.getUnreadMessageCount());
Message msg[] = pop3.getMessages();
for (int i=0; i < msg.length; i++) {
MimeMessage m = (MimeMessage) msg[i];
Address from[] = m.getFrom();
log.info("Message #"+i+
" From:"+from[0].toString()+
" Subject:"+m.getSubject());
Object msgContent = m.getContent();
log.info("Message contents: "+msgContent);
//
//Figure out the format of the message and process it
//
String msgBody = "";
//
//This is an example of looping through the various parts of a
//Mime multipart message
//
if (msgContent instanceof MimeMultipart) {
MimeMultipart mp = (MimeMultipart) msgContent;
log.debug("Message casted to a MimeMultiPart.");
//
//If the message is a mime-multipart, then loop through the parts looking
//for key information
//
if (mp != null) {
for (int j=0; j < mp.getCount(); j++) {
//log.debug("About to get MimeBodyPart #"+j);
MimeBodyPart bp = (MimeBodyPart) mp.getBodyPart(j);
//log.debug("Got MimeBodyPart #"+j);
if (bp.getContent() instanceof String) {
msgBody = (String) bp.getContent();
log.info("Body:"+msgBody);
}
else {
log.info("Mimebodypart is not a string. Need to " +
"process the byte stream instead.");
}
}
}
}
//
//This is how to get the body of a plain old text message
//Just a regular text message, print it out
//
else if (msgContent instanceof String) {
msgBody = (String) msgContent;
log.info("Body:"+msgBody);
}
//
//Another message format type. Need to process some other way
//
else {
log.info("Unable to process email message. Its contents are " +
"not a String or MimeMultipart type.");
}
//
//Delete the message
//
//msg[i].setFlag(Flag.DELETED, true);
}
pop3.disconnect();
} catch (Exception e) {
log.error("Error:"+e.toString());
}
}
}
Now that you have the code, look in the main method for a line that looks like:
POP3 pop3 = new POP3("192.168.1.50", "tima", "mypassword");
This is the only line you should have to modify to test out the code. You will want to put in the IP address or hostname of your POP3 server, your POP3 userid, and lastly your password.
The class should then be able to run and print out your unread message count, and then loop through each message printing out who it’s from, its subject, and lastly the message body. You'll notice that I have the line of code commented out to delete the messages from your POP3 server. If you want your application to delete the messages after it processes them, uncomment the line that looks like:
//msg[i].setFlag(Flag.DELETED, true);
Hopefully this example will get you started in using the JavaMail packages to check a POP3 account. All in all its pretty easy to do. Once you get the basic body of the email, your application can parse the text to intelligently process it. Happy java-mailing!

del.icio.us
Digg
StumbleUpon