OK, back to the task at hand. If we are successful at connecting, we can do some real work with our Gmail account. Sending and receiving messages with attachments, multipart messages, HTML messages, etc. is beyond the scope of these posts since this is just a basic intro that will cover only the basic concepts of JavaMail and connecting to a hosted email account. We will just focus on plain text.
First, let’s look at sending email. As stated, the Transport object handles this. Keep in mind that we are only scratching the surface of what the JavaMail API can do. Once you are familiar with the basics, you can do just about anything fairly easily.
/** * Sends a plain text email * @param to * @param subject * @param text * @throws SimpleGmailClientException */ public void sendMessage(String to, String subject, String text) throws SimpleGmailClientException { Message message = new MimeMessage(session); try { message.setFrom(new InternetAddress("test@gmail.com")); message.setRecipient(Message.RecipientType.TO, new InternetAddress(to)); message.setSubject(subject); message.setText(text); } catch (AddressException ae) { throw new SimpleGmailClientException("Invalid internet address", ae); } catch (MessagingException me) { throw new SimpleGmailClientException("Error creating message", me); } try { transport.sendMessage(message, message.getAllRecipients()); } catch (MessagingException me) { throw new SimpleGmailClientException("Error sending message", me); } }
As you can see, the code is pretty basic and straight forward. The method takes Strings for the “to” address, the subject, and the message text. One of the more complicated things is handling the exceptions that JavaMail will throw. In this case, I am wrapping all the exceptions in my own exception to add a friendlier message about where an error occurred. You can, of course, decide to throw the exceptions out to make the code a little cleaner and apply your own exception handling scheme if you wish. When learning from a newbie’s perspective, though, I think that using the code the way it is will help point errors back to a recognizable point.
Next, let’s look at reading email. In this case, I am simply going to take a String for a message subject to search for and read. When the message with the subject is found, a simple String representation of it is returned. Otherwise the method will return null.
/** * Reads an email message with a given subject. * Returns null if the subject is not found. * @param subject * @return A simple String representation of an email message, * null if not found * @throws SimpleGmailClientException */ public String readMessage(String subject) throws SimpleGmailClientException { String messageString = null; try { for (Message message : Arrays.asList(inbox.getMessages())) { if (message.getSubject().equals(subject)) { messageString = "To: " + Arrays.asList(message.getAllRecipients()) + "n" + "From: " + Arrays.asList(message.getFrom()) + "n" + "Sent: " + message.getSentDate() + "n" + "Subject: " + message.getSubject() + "n" + "Text: " + message.getContent(); break; } } } catch (MessagingException me) { throw new SimpleGmailClientException("Error reading Gmail Inbox", me); } catch (IOException e) {/* Not using streams, only plain text */} return messageString; }
One other aside here, this is where a lot of confusion comes from as well. The user interface for most email clients place “deleted” messages in a “Deleted Messages” or “Trash” folder, but flagging and expunging in JavaMail does not. Messages that are expunged from folders with this technique are deleted forever! To emulate the way the UI works, you would have to explicitly move the message to the “Deleted Messages” or “Trash” folder with that folder’s appendMessages() method.
All that’s left is to create a main() method to use the client. To demonstrate the send and receive capabilities, we will login, send a message to ourselves, give it some time to arrive, read it, delete it, and logout. All you need to know is your Gmail username and password.
package com.e_gineering.simplegmailclient; public class Main { /** * @param args */ public static void main(String[] args) { SimpleGmailClient client = new SimpleGmailClient(); String subject = "This is a Test"; try { String username = "{INSERT YOUR USERNAME HERE}"; String password = "{INSERT YOUR PASSWORD HERE}"; client.login(username, password); client.sendMessage(username + "@gmail.com", subject, "This is some test text"); // Give the message some time to arrive... try {Thread.sleep(10000l);} catch (InterruptedException e) {} String message = client.readMessage(subject); System.out.println(message); client.deleteMessage(subject); client.logout(); } catch (SimpleGmailClientException sgce) { sgce.printStackTrace(); } } }
package com.e_gineering.simplegmailclient; /** * Wrapper Exception for exceptions thrown inside SimpleGmailClient * @author christian.desserich */ @SuppressWarnings("serial") public class SimpleGmailClientException extends Exception { /** * @param message * @param cause */ public SimpleGmailClientException(String message, Throwable cause) { super(message, cause); } }
I hope that this helps people get started using JavaMail and gets people to stop putting SMTP socket factory, SMTP port, and various other extraneous properties in their code. It is not necessary! I also hope this will put to bed all the questions about how to interface with Gmail via Java. There is, of course, so much more you can do with the JavaMail API. There are hooks to use it with a GUI front end, for example the Session factory method will take an Authenticator argument. The Message classes enable you to create complicated emails with attachments, multi-part messages, HTML messages, etc. There are folder listeners that enable you to monitor the status of the messages contained within. The list goes on and on
Sources:
http://java.sun.com/products/javamail/JavaMail-1.4.pdf
http://java.sun.com/products/javamail/javadocs/index.html
http://java.sun.com/products/javamail/FAQ.html