Receiving mails in Java with IMAP or POP3
I was recently in need to write some small demo project which was receiving and processing mails. There is a lot of documentation for sending mails, but gathering information about the receiving and processing part is less easy.
This example shows you how to receive mails in Java either using the IMAP or the POP3 protocol. The SSL encrypted variants IMAPS and POP3S are also supported. Received mails will be set to read, which means that you will only receive the latest ones. I will also give some hints about how to handle incoming mails concerning application security. Remember to alwalys sanitize user inputs.
Receiving mails
You need to use to the following import statement import javax.mail.*;
to be able to connect mail servers.
The constructor of the client is straightforward.
It is simply used to pass and store some values into fields, which are then used later on.
We are interested in the protocol, host, port user and password.
Valid values for the protocol are imap, imaps, pop3 and pop3s.
We use the following code sample to connect to the mail server.
First we have to create new properties and add values with the defined protocol, host and port.
We use these properties to create a Session.
With this session we can create a Store and connect to the server using the given username and password.
Afterwards we get the inbox folder and open it in read write mode.
Inbox usually is the default folder.
If you want to get a different one, just change this string.
The folder is opened also in write mode to mark mails as read.
We pass this folder into the getNewMails
method to receive the latest mails.
There is some wrapping of exceptions into runtime exceptions in the end.
Folder and Store also have to be disconnected in the end.
The getNewMails
method gets all the messages in the folder.
An if condition is used to only process unseen messages.
Afterwards the message is set to seen.
Keep in mind that no data is beeing deleted.
When processing big volumes of mails your folder gets bigger quite fast.
You might want to delete messages, instead of marking them as read, to keep the mail processing short.
The code uses a for loop to avoid race conditions.
In case there are multiple mail clients connected mails are not processed multiple times.
A mapping to an internal class is needed, because an exception is thrown as soon as you try to access a message who’s session has been closed. Another reason is the sanitizing of user inputs. You can read more about this in the next chapter.
The class can also be found on GitHub.
The error handling is just an example how it could be done. Depending on your needs you might want to use a more sophisticated one.
In the end a List of mails is returned. The mail class is just a simple data class containing information we extract from the messages on the mail server. For my minimal example I was only interested in the subject, the content, the sender and the recipient (even though there can be more than one recipient). You can extract even more informations from the messages. The documentation of the class can be found here.
You can read more about the mapping in the next chapter.
Sanitizing received Mails
When you are dealing with user input (you could also count mails to this) you should always worry about code injections. The best way to prevent these is sanitizing the inputs you receive. You can obviously do this with mails as well. OWASP provides a nice utility called Encoder to do that. I use a simple helper class with static methods to do the mapping. All the attributes received by mail will be encoded for displaying it in HTML. The encoder also brings methods for inserting your mail attributes into e.g. JavaScript or CSS. We simply extract the things we are interested in from the message and sanitize the input using the encoder before creating a new mail object with the attributes.
The class can also be found on GitHub.
Usage
To get started simply fill in the constructor’s parameters to connect to your mail server.
An example for IMAP might look something like this:
new MailReceiveClient("imap", "localhost", "143", "user", "password");
And for POP3 like this:
new MailReceiveClient("pop3", "localhost", "110", "user", "password");
You could also use Spring to create a bean using the Component
annotation and set the constructor’s parameters via properties using the Value
annotation. This is the way I am doing it in my demo project.
If you do not know how to easily start up a local (mock) mailserver you can use GreenMail to do that. I have written an article how to integrate it into you local environment.
Testing
There is quite some logic in this piece of code apart from the connection to the server. Things that should get tested. I recently held a presentation at a meetup about testing mails. You can use this resource to get started. Along to the repo I wrote a test for this class, which you can check out on GitHub. There might also be a follow up article in the future about testing emails in Java.
As always full source code is available on GitHub.