Appearance
Receiving Email
In the previous section, we discussed the process of sending emails, where the client always sends emails to an MTA using the SMTP protocol.
Receiving emails is the opposite process. Since emails ultimately arrive at the recipient's MDA server, receiving an email involves the recipient using their client to fetch the email from the MDA server to their local machine.
The most widely used protocol for receiving emails is POP3: Post Office Protocol version 3, which is also a protocol built on top of a TCP connection. The standard port for POP3 servers is 110, and if the entire session needs to be encrypted, the encrypted port 995 is used.
Another protocol for receiving emails is IMAP: Internet Mail Access Protocol, which uses standard port 143 and encrypted port 993. The main difference between IMAP and POP3 is that IMAP automatically synchronizes all local operations with the server and allows users to create folders in the email server's inbox.
JavaMail also provides support for the IMAP protocol. Since the usage of POP3 and IMAP is very similar, we will only introduce the usage of POP3 here.
Using POP3 to Receive Emails
When using POP3 to receive emails, we do not need to worry about the underlying POP3 protocol because JavaMail provides high-level interfaces. First, we need to connect to a Store
object:
java
// Prepare login information:
String host = "pop3.example.com";
int port = 995;
String username = "bob@example.com";
String password = "password";
Properties props = new Properties();
props.setProperty("mail.store.protocol", "pop3"); // Protocol name
props.setProperty("mail.pop3.host", host); // POP3 host name
props.setProperty("mail.pop3.port", String.valueOf(port)); // Port number
// Enable SSL:
props.put("mail.smtp.socketFactory.class", "javax.net.ssl.SSLSocketFactory");
props.put("mail.smtp.socketFactory.port", String.valueOf(port));
// Connect to the Store:
URLName url = new URLName("pop3", host, port, "", username, password);
Session session = Session.getInstance(props, null);
session.setDebug(true); // Enable debug information
Store store = new POP3SSLStore(session, url);
store.connect();
A Store
object represents the entire mailbox storage. To retrieve emails, we need to access a specific Folder
(directory) through the Store
, usually INBOX
which represents the inbox:
java
// Get the inbox:
Folder folder = store.getFolder("INBOX");
// Open in read-write mode:
folder.open(Folder.READ_WRITE);
// Print total messages/new messages/unread messages/deleted messages:
System.out.println("Total messages: " + folder.getMessageCount());
System.out.println("New messages: " + folder.getNewMessageCount());
System.out.println("Unread messages: " + folder.getUnreadMessageCount());
System.out.println("Deleted messages: " + folder.getDeletedMessageCount());
// Retrieve each email:
Message[] messages = folder.getMessages();
for (Message message : messages) {
// Print each email:
printMessage((MimeMessage) message);
}
When we obtain a Message
object, we can cast it to a MimeMessage
and then print out the email's subject, sender, recipient, and other information:
java
void printMessage(MimeMessage msg) throws IOException, MessagingException {
// Email subject:
System.out.println("Subject: " + MimeUtility.decodeText(msg.getSubject()));
// Sender:
Address[] froms = msg.getFrom();
InternetAddress address = (InternetAddress) froms[0];
String personal = address.getPersonal();
String from = personal == null ? address.getAddress() : (MimeUtility.decodeText(personal) + " <" + address.getAddress() + ">");
System.out.println("From: " + from);
// Continue printing recipients:
...
}
Retrieving the email body is somewhat cumbersome. A MimeMessage
object is also a Part
object; it may contain only text or be a Multipart
object composed of several Part
objects. Therefore, we need to recursively parse the complete body:
java
String getBody(Part part) throws MessagingException, IOException {
if (part.isMimeType("text/*")) {
// Part is text:
return part.getContent().toString();
}
if (part.isMimeType("multipart/*")) {
// Part is a Multipart object:
Multipart multipart = (Multipart) part.getContent();
// Iterate through each sub-Part:
for (int i = 0; i < multipart.getCount(); i++) {
BodyPart bodyPart = multipart.getBodyPart(i);
String body = getBody(bodyPart);
if (!body.isEmpty()) {
return body;
}
}
}
return "";
}
Finally, remember to close the Folder
and Store
:
java
folder.close(true); // Passing true means that delete operations will be synchronized to the server (i.e., deleting emails from the server's inbox)
store.close();
Exercise
Use POP3 to receive emails.
Summary
- When receiving emails with Java, you can use either the POP3 or IMAP protocol.
- When using the POP3 protocol, you need to include the JavaMail dependencies in your Maven project, determine the POP3 server's domain/name, port, whether to use SSL, etc., and then use the relevant APIs to receive emails.
- Enabling debug mode allows you to view detailed communication content, facilitating error troubleshooting.