Java™ - Retrieve Contents of an Email Remotely with Gmail SMTPS
What Will I Learn?
In this tutorial, I will continue my previous lesson about how to manipulate email via Java™ application that all classes are available in the javax.mail package. Previously we already know how to send an email with attachments, now we will try to retrieve and read all existing emails on our Gmail account.
- Java™ I/O Stream
- Java™ Mail
- Java™ Functional Interfaces
Requirements
- Any current JDK.
- IntelliJ IDEA Community.
- Target google account.
Before we get started, make sure to change theAllow less secure apps
:ON
setting on the target account here.
Difficulty
- Basic
Tutorial Contents
Prepare Connection To the Target Folder
In this case, we will retrieve and read all emails in the
Inbox
folder.public static void retrieve(String username, String password) { Session session = Session.getDefaultInstance(GMAIL); try { Store store = session.getStore("imaps"); store.connect(GMAIL.getProperty("mail.smtp.host"), username, password); Folder inbox = store.getFolder("Inbox"); inbox.open(Folder.READ_ONLY); /* * Right now, the folder is ready */ { inbox.getMessages(); } inbox.close(false); store.close(); } catch(Throwable e) { e.printStackTrace(); } }
Read Headers of Email
We will read
From
,To
,Cc
,Bcc
and the Subject of Email.private static void print(Part part) throws Throwable { if(part instanceof Message) { Message message = (Message) part; // From System.out.println("From: [" + print(message.getFrom()) + "]"); // To System.out.println(" To: [" + print(message.getRecipients(Message.RecipientType.TO)) + "]"); // CC System.out.println(" Cc: [" + print(message.getRecipients(Message.RecipientType.CC)) + "]"); // BCC System.out.println(" Bbc: [" + print(message.getRecipients(Message.RecipientType.BCC)) + "]"); // Subject System.out.println("Subject: " + message.getSubject()); } }
private static String print(Address[] accounts) { if(accounts == null) return ""; StringBuilder plain = new StringBuilder(accounts[0].toString()); for(int i = 0, n = accounts.length; ++i < n;) plain.append(";" + accounts[i]); return plain.toString(); }Define Functions for Handling Any Types of Message Bodies
We will handle the type of message bodies:
image
,multipart
and plain string as the default. Next, we will try to handle the other types.
The content of an email (usually known asPart
) is available in various formats:- As a DataHandler - using the
getDataHandler()
method. The content of aPart
is also available through ajavax.activation.DataHandler
object. The DataHandler object allows clients to discover the operations available on the content, and to instantiate the appropriate component to perform those operations. - As an InputStream - using the
getInputStream()
method. Any mail-specific encodings are decoded before this stream is returned. - As a Java Object - using the
getContent()
method. This method returns the content as a Java object. The returned object is of course dependent on the content itself. In particular, a multipart Part's content is always aMultipart
or subclass thereof. That is,getContent()
on a multipart typePart
will always return aMultipart
(or subclass) object.
References- javax.mail.Part - The common base interface for Messages and BodyParts.
- javax.mail.Multipart - The container that holds multiple body parts. Multipart provides methods to retrieve and set its subparts.
- javax.mail.internet.MimeMultipart - An implementation of the abstract
Multipart
class that uses MIME conventions for the multipart data.
private static final Map<String, Function<Object, Void>> FUNCTIONS = new java.util.HashMap<>(); private static final String IMG_JPEG = "image/jpeg"; private static final String MULTIPART = "multipart/*";
static { //Default action FUNCTIONS.put(null, content -> { System.out.println(content); return null; }); FUNCTIONS.put(MULTIPART, content -> { Multipart multiPart; try { multiPart = (Multipart) content; } catch(Throwable e) { System.out.println("Parsing content was unsuccessful"); e.printStackTrace(); return null; } int i, n; try { n = multiPart.getCount(); } catch(Throwable e) { System.out.println("Getting count of this content was unsuccessful"); n = 0; } for(i = 0; i < n; i++) try { print(multiPart.getBodyPart(i)); } catch(Throwable e) { e.printStackTrace(); } return null; }); FUNCTIONS.put(IMG_JPEG, content -> { InputStream in; try { in = (InputStream) content; } catch(Throwable e) { System.out.println("Parsing content was unsuccessful"); e.printStackTrace(); return null; } final byte[] BYTES = new byte[2048]; System.out.println("Enter image path and name of this current content: "); String name; try(BufferedReader reader = new BufferedReader(new InputStreamReader(System.in))) { if((name = reader.readLine()) == null || name.length() < 1) throw new UnsupportedOperationException("Name should not be empty"); } catch(Throwable e) { System.out.println("Scanning name was unsuccessful"); e.printStackTrace(); return null; } try(FileOutputStream writer = new FileOutputStream(name)) { for(int length; ; writer.write(BYTES, 0, length)) if((length = in.read(BYTES)) < 0) break; } catch(Throwable e) { e.printStackTrace(); } return null; }); }
private static void print(Part part) throws Throwable { if(part instanceof Message) { Message message = (Message) part; System.out.println("From: [" + print(message.getFrom()) + "]"); System.out.println(" To: [" + print(message.getRecipients(Message.RecipientType.TO)) + "]"); System.out.println(" Cc: [" + print(message.getRecipients(Message.RecipientType.CC)) + "]"); System.out.println(" Bbc: [" + print(message.getRecipients(Message.RecipientType.BCC)) + "]"); System.out.println("Subject: " + message.getSubject()); } /* * Additional logic */ if(part.isMimeType("text/plain") || part.isMimeType("message/rfc822")) FUNCTIONS.get(null).apply(part.getContent()); else if(part.isMimeType(MULTIPART)) FUNCTIONS.get(MULTIPART).apply(part.getContent()); else if(part.isMimeType(IMG_JPEG) || part.getContentType().contains("image/")) FUNCTIONS.get(IMG_JPEG).apply(part.getContent()); else { Object content = part.getContent(); if(content instanceof InputStream) { InputStream in = (InputStream) content; for(int c; (c = in.read()) > -1; ) System.out.write(c); } else System.out.println(content.toString()); System.out.println("*** THE END ***"); } }- As a DataHandler - using the
Testing
Main
public static void main(String[] args) {
String username = "rezanas************";
String password = "*******************";
retrieve(username, password);
}
public static void retrieve(String username, String password) {
Session session = Session.getDefaultInstance(GMAIL);
try {
Store store = session.getStore("imaps");
store.connect(GMAIL.getProperty("mail.smtp.host"), username, password);
Folder inbox = store.getFolder("Inbox");
inbox.open(Folder.READ_ONLY);
/*
* Listen input from the user
*/
String line;
int i = 0, n = inbox.getMessageCount();
try(BufferedReader reader = new BufferedReader(new InputStreamReader(System.in))) {
do {
print(inbox.getMessage(n -= (i + 1)));
System.out.print("To stop, type \"0\" (zero) or type any positive number to jump: ");
line = reader.readLine();
try{ i = Integer.parseInt(line); }
catch(Throwable e) { i = 0; }
}
while(!line.equals("0"));
}
inbox.close(false);
store.close();
}
catch(Throwable e) { e.printStackTrace(); }
}
Result
Final Source Code
public class Mail {
public static void main(String[] args) {
String username = "rezanas***********";
String password = "******************";
retrieve(username, password);
}
public static void retrieve(String username, String password) {
Session session = Session.getDefaultInstance(GMAIL);
try {
Store store = session.getStore("imaps");
store.connect(GMAIL.getProperty("mail.smtp.host"), username, password);
Folder inbox = store.getFolder("Inbox");
inbox.open(Folder.READ_ONLY);
String line;
int i = 0, n = inbox.getMessageCount();
try(BufferedReader reader = new BufferedReader(new InputStreamReader(System.in))) {
do {
print(inbox.getMessage(n -= (i + 1)));
System.out.print("To stop, type \"0\" (zero) or type any positive number to jump: ");
line = reader.readLine();
try{ i = Integer.parseInt(line); }
catch(Throwable e) { i = 0; }
}
while(!line.equals("0"));
}
inbox.close(false);
store.close();
}
catch(Throwable e) { e.printStackTrace(); }
}
private static final Map<String, Function<Object, Void>> FUNCTIONS = new java.util.HashMap<>();
private static final String IMG_JPEG = "image/jpeg";
private static final String MULTIPART = "multipart/*";
static {
//Default action
FUNCTIONS.put(null, content -> {
System.out.println(content);
return null;
});
FUNCTIONS.put(MULTIPART, content -> {
Multipart multiPart;
try { multiPart = (Multipart) content; }
catch(Throwable e) {
System.out.println("Parsing content was unsuccessful");
e.printStackTrace();
return null;
}
int i, n;
try {
n = multiPart.getCount();
} catch(Throwable e) {
System.out.println("Getting count of this content was unsuccessful");
n = 0;
}
for(i = 0; i < n; i++)
try { print(multiPart.getBodyPart(i)); }
catch(Throwable e) { e.printStackTrace(); }
return null;
});
FUNCTIONS.put(IMG_JPEG, content -> {
InputStream in;
try { in = (InputStream) content; }
catch(Throwable e) {
System.out.println("Parsing content was unsuccessful");
e.printStackTrace();
return null;
}
final byte[] BYTES = new byte[2048];
System.out.println("Enter image path and name of this current content: ");
String name;
try(BufferedReader reader = new BufferedReader(new InputStreamReader(System.in))) {
if((name = reader.readLine()) == null || name.length() < 1)
throw new UnsupportedOperationException("Name should not be empty");
} catch(Throwable e) {
System.out.println("Scanning name was unsuccessful");
e.printStackTrace();
return null;
}
try(FileOutputStream writer = new FileOutputStream(name)) {
for(int length; ; writer.write(BYTES, 0, length))
if((length = in.read(BYTES)) < 0)
break;
} catch(Throwable e) { e.printStackTrace(); }
return null;
});
}
private static void print(Part part) throws Throwable {
if(part instanceof Message) {
Message message = (Message) part;
System.out.println("From: [" + print(message.getFrom()) + "]");
System.out.println(" To: [" + print(message.getRecipients(Message.RecipientType.TO)) + "]");
System.out.println(" Cc: [" + print(message.getRecipients(Message.RecipientType.CC)) + "]");
System.out.println(" Bbc: [" + print(message.getRecipients(Message.RecipientType.BCC)) + "]");
System.out.println("Subject: " + message.getSubject());
}
if(part.isMimeType("text/plain") || part.isMimeType("message/rfc822"))
FUNCTIONS.get(null).apply(part.getContent());
else if(part.isMimeType(MULTIPART))
FUNCTIONS.get(MULTIPART).apply(part.getContent());
else if(part.isMimeType(IMG_JPEG) || part.getContentType().contains("image/"))
FUNCTIONS.get(IMG_JPEG).apply(part.getContent());
else {
Object content = part.getContent();
if(content instanceof InputStream) {
InputStream in = (InputStream) content;
for(int c; (c = in.read()) > -1; )
System.out.write(c);
} else
System.out.println(content.toString());
System.out.println("*** THE END ***");
}
}
private static String print(Address[] accounts) {
if(accounts == null) return "";
StringBuilder plain = new StringBuilder(accounts[0].toString());
for(int i = 0, n = accounts.length; ++i < n;)
plain.append(";" + accounts[i]);
return plain.toString();
}
}
Thank you!
Share with Heart.
Curriculum
Posted on Utopian.io - Rewarding Open Source Contributors
Thank you for the contribution. It has been approved.
You can contact us on Discord.
[utopian-moderator]
Hey @murez-nst I am @utopian-io. I have just upvoted you!
Achievements
Suggestions
Get Noticed!
Community-Driven Witness!
I am the first and only Steem Community-Driven Witness. Participate on Discord. Lets GROW TOGETHER!
Up-vote this comment to grow my power and help Open Source contributions like this one. Want to chat? Join me on Discord https://discord.gg/Pc8HG9x