• Skip to main content
  • Skip to header right navigation
  • Skip to site footer
E-gineering

E-gineering

  • Who We Are
    • Our Story
    • Leadership Team
    • Whole Team
  • What We Do
    • Practices
    • Full Services
    • Success Stories
  • Working Here
    • Careers
    • Work Life
    • Community Life
    • Fun Life
  • Blog
  • Contact Us

JavaMail and Gmail Simplified Part 3: The Code, Logging In

June 25, 2009 by Christian Desserich

Mail-01Finally!! Let’s look at some code. Here is a simple Gmail client object in its entirety

package com.e_gineering.simplegmailclient;

import java.io.IOException;
import java.util.Arrays;
import java.util.Properties;

import javax.mail.Flags;
import javax.mail.Folder;
import javax.mail.Message;
import javax.mail.MessagingException;
import javax.mail.NoSuchProviderException;
import javax.mail.Session;
import javax.mail.Store;
import javax.mail.Transport;
import javax.mail.internet.AddressException;
import javax.mail.internet.InternetAddress;
import javax.mail.internet.MimeMessage;

/**
 * A simple email client that will send and receive email with a hosted Gmail account
 * @author christian.desserich
 */
public class SimpleGmailClient {
    private Session session;
    private Transport transport;
    private Store store;
    private Folder inbox;
    private static final String INBOX = "INBOX";

    /**
     * Logs in to a Gmail account
     * @param username
     * @param password
     * @throws SimpleGmailClientException
     */
    public void login(String username, String password) throws SimpleGmailClientException {

        session = Session.getInstance(new Properties());

        try {

            transport = session.getTransport("smtps");
            transport.connect("smtp.gmail.com", username, password);

        } catch (NoSuchProviderException nspe) {
            throw new SimpleGmailClientException("Error getting Gmail Transport", nspe);
        } catch (MessagingException me) {
            throw new SimpleGmailClientException("Error connecting to Gmail Transport", me);
        }

        try {

            store = session.getStore("imaps");
            store.connect("imap.gmail.com", username, password);

        } catch (NoSuchProviderException nspe) {
            throw new SimpleGmailClientException("Error getting Gmail Store", nspe);
        } catch (MessagingException me) {
            throw new SimpleGmailClientException("Error connecting to Gmail Store", me);
        }

        try {

            inbox = store.getFolder(INBOX);
            inbox.open(Folder.READ_WRITE);

        } catch (MessagingException me) {
            throw new SimpleGmailClientException("Error opening Gmail Inbox", me);
        }
    }

    /**
     * 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);
        }
    }

    /**
     * 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;
    }

    /**
     * Deletes (permanently) an email message with the given subject
     * @param subject
     * @throws SimpleGmailClientException
     */
    public void deleteMessage(String subject) throws SimpleGmailClientException {

        try {

            for (Message message : Arrays.asList(inbox.getMessages())) {
                if (message.getSubject().equals(subject)) {
                    message.setFlag(Flags.Flag.DELETED, true);
                    break;
                }
            }

        } catch (MessagingException me) {
            throw new SimpleGmailClientException("Error reading Gmail Inbox", me);
        }

        try {

            inbox.expunge();

        } catch (MessagingException me) {
            throw new SimpleGmailClientException("Error deleting messages from Gmail Inbox", me);
        }
    }

    /**
     * Logs out of Gmail
     */
    public void logout() {
        if (transport != null) {
            try {transport.close();} catch (MessagingException me) {/* We could log this error */}
        }

        if (store != null) {
            try {store.close();} catch (MessagingException me) {/* We could log this error */}
        }
    }
}

Fist let’s dissect each piece. This is the setup and connection code:

/**
* Logs in to a Gmail account
* @param username
* @param password
* @throws SimpleGmailClientException
*/
public void login(String username, String password) throws SimpleGmailClientException {

session = Session.getInstance(new Properties());

try {

transport = session.getTransport("smtps");
transport.connect("smtp.gmail.com", username, password);

} catch (NoSuchProviderException nspe) {
throw new SimpleGmailClientException("Error getting Gmail Transport", nspe);
} catch (MessagingException me) {
throw new SimpleGmailClientException("Error connecting to Gmail Transport", me);
}

try {

store = session.getStore("imaps");
store.connect("imap.gmail.com", username, password);

} catch (NoSuchProviderException nspe) {
throw new SimpleGmailClientException("Error getting Gmail Store", nspe);
} catch (MessagingException me) {
throw new SimpleGmailClientException("Error connecting to Gmail Store", me);
}

try {

inbox = store.getFolder(INBOX);
inbox.open(Folder.READ_WRITE);

} catch (MessagingException me) {
throw new SimpleGmailClientException("Error opening Gmail Inbox", me);
}
}

Notice the creation of the empty Propeties object to hand to the factory method. This is where you could potentially read in a properties file with the load() methods that will take a Reader or InputStream. As stated (many, many times), we will hand in our info as we go, instead. In this case, I am connecting to both the SMTP and IMAP servers so we can have both send and receive capabilities. If you only need one or the other of course you can split out the code as you please.

The other interesting thing going on here is the opening of the “INBOX” folder. The Store object is represented as a folder hierarchy. There is the “default folder” that is the top level of the hierarchy. Servers can have the “INBOX” folder as the default folder, apparently, but in Gmail’s case, the conceptual inbox is contained in the default folder along with another folder hierarchy that I will explain below. If you are going to apply this code to a different host besides Gmail, it is supposed to be standard that all mail servers have a folder, called “INBOX” that you can access, but don’t count on it unless you know its there.

So to open the inbox, we have to explicitly get it by passing its name to the getFolder() method. JavaMail will automatically search down the hierarchy to find the folder name you pass into the method, so there is no need to loop through the hierarchy to find and get a certain folder. If you have the name correct, JavaMail will find it. The other thing going on is that you have to explicitly open a folder with read-only or read-write access. If you attempt to open a folder with read-write permissions, but are forbidden to do so, an exception is thrown.

Here’s a quick overview of Gmail’s IMAP folder hierarchy. Inside the default folder (“”) there is the “INBOX” folder which we are already familiar with and the “[Gmail]” folder which we are not.

Default_folder

Inside the “[Gmail]” folder, there are the Gmail specific folders like the sent mail folder. These folders are where you could do things like purge sent mail, move messages to other folders, delete spam, etc.

[Gmail]_folder

Category: Enterprise

About Christian Desserich

Previous Post:JavaMail and Gmail Simplified Part 2: The Objects
Next Post:JavaMail and Gmail Simplified Part 4: The Code, Sending and Receiving

Let’s work together

Get in touch with us and send some basic info about your project.

Get in touch!

Social

Follow along on social media

  • Mail
  • Facebook
  • GitHub
  • Instagram
  • LinkedIn
  • Twitter

Navigation

Home

Who We Are

What We Do

Working Here

Blog

Contact Us

Contact

8415 Allison Pointe Blvd
Suite 200
Indianapolis, IN 46250

317.348.1780

info@e-gineering.com

© Copyright 2023 | E-gineering, Inc.

Return to top