I am using JavaMail Api to read mails from gmail account. But problem is that I can read it only once. Is there any way to read the mails again and again???
My Java Code is :
import java.util.Properties;
import javax.mail.BodyPart;
import javax.mail.Folder;
import javax.mail.Message;
import javax.mail.MessagingException;
import javax.mail.Multipart;
import javax.mail.NoSuchProviderException;
import javax.mail.Session;
import javax.mail.Store;
public class Main {
// main function. Project run starts from main function...
public static void main(String[] args) {
String host = "pop.gmail.com";// change accordingly
String mailStoreType = "pop3";
String username = "your_email#gmail.com";// change accordingly
String password = "your_password";// change accordingly
check(host, mailStoreType, username, password);
}
// function to make connection and get mails from server known as "Pop" server
public static void check(String host, String storeType, String user, String password)
{
try {
//create properties field
Properties properties = new Properties();
properties.put("mail.pop3.host", host);
properties.put("mail.pop3.port", "995");
properties.put("mail.pop3.starttls.enable", "true");
Session emailSession = Session.getDefaultInstance(properties);
//create the POP3 store object and connect with the pop server
Store store = emailSession.getStore("pop3s");
store.connect(host, user, password);
//create the folder object and open it
Folder emailFolder = store.getFolder("Inbox");
emailFolder.open(Folder.READ_ONLY);
// retrieve the messages from the folder in an array and print it
Message[] messages = emailFolder.getMessages();
System.out.println("messages.length---" + messages.length);
for (int i = 0, n = messages.length; i < n; i++) {
Message message = messages[i];
Object obj = message.getContent();
Multipart mp = (Multipart)obj;
BodyPart bp = mp.getBodyPart(0);
System.out.println("---------------------------------");
System.out.println("Email Number " + (i + 1));
System.out.println("Subject: " + message.getSubject());
System.out.println("From: " + message.getFrom()[0]);
System.out.println("To: " + message.getAllRecipients().toString());
System.out.println("Received Date:" + message.getReceivedDate());
System.out.println("Text: " + bp.getContent().toString());
}
//close the store and folder objects
emailFolder.close(false);
store.close();
} catch (NoSuchProviderException e) {
e.printStackTrace();
} catch (MessagingException e) {
e.printStackTrace();
} catch (Exception e) {
e.printStackTrace();
}
}
}
In this code I am using pop server to read emails from and now I give email and password in it and run. It works fine but it reads an email once only, next time if I run program , kit gives me number of messages equal to 0...
I want to read messages again and again as many times as I want...
Any help will be appreciated...
If you want to get All Emails every time, IMAP sever will be best for it.
You can change the mail server to
IMAP.gmail.com
and the port will be 993 (considering you are using gmail account).
The Link sidgate provided will be best example for you.
Gmail has user settings for how pop3 mail requests are handled. I was having this same issue, and ended up checking out this page: https://javaee.github.io/javamail/FAQ#gmailsettings.
To see all email every time, you need to enable the flag (in the settings page): Enable POP for all mail (even mail that's already been downloaded)
Did the trick for me. Hope that helps.
Related
I am using the code from this tutorial with minimal modifications. Here is my code: `
public static void receiveEmail(String hst, String stype, String user, String password) {
try {
Properties props = new Properties();
props.put("mail.store.protocol", "pop3");
props.put("mail.pop3s.host", hst);
props.put("mail.pop3s.port", "995");
props.put("mail.pop3.starttls.enable", "true");
Session sess = Session.getDefaultInstance(props);
Store st = sess.getStore("pop3s");
st.connect(hst, user, password);
Folder emailFolder = st.getFolder("INBOX");
emailFolder.open(Folder.READ_ONLY);
Message[] messages = emailFolder.getMessages();
Message message = messages[229];
System.out.println("Welcome To Email");
System.out.println("Subject: " + message.getSubject());
System.out.println("From: " + message.getFrom()[0]);
String body = "body";
Multipart part = (Multipart) message.getContent();
MimeBodyPart mimePart = null;
for (int i = 0; i < part.getCount(); i++) {
mimePart = (MimeBodyPart) part.getBodyPart(i);
System.out.println(mimePart.getContent());
System.out.println("========");
}
emailFolder.close(false);
st.close();
}// catch (NoSuchProviderException e) {e.printStackTrace();}
catch (MessagingException e) {e.printStackTrace();}
catch (IOException e) {e.printStackTrace();}
}
`
I am calling receive email from a driver class. This is literally the only method being called.
I will run the code and it will work fine, printing the contents of the 229th email. Then, if i run it again, with not changes whatsoever, I get an array index out of bounds exception saying index 229 is out of bounds for length 229. As I understand it, when i run it, the code works fine, but somehow the email I want to access is no longer accessible. I have been trying to access the last email for testing purposes and I knew which number it is. What I think is happening is that the code is making the email I just accessed unavailable. I just added a print line and confirmed that when i first run it, the length is such that the message being accessed is the last element in the array, upon running the program again, the array is mysteriously one element smaller. I have verified that the emails are actually not disappearing from my account. I think i started at email 250 or something and have been gradually losing access. Another interesting thing to note is that yesterday, I was working with a different email account that only had 19 emails in it, after a short period of time, I was suddenly unable to list out the emails in that account with code. The emails were there, I could send emails with code, but not access the emails stored on that account.
My email program is not retrieving mail properly.
Before it used to display something like javax.mail.internet.MimeMultipart#787171
now that I solved it using BodyPart() it won't retrieve emails it already retrieved. The funny thing is that the emails aren't deleted from my account, it just won't count or shows them again. Also, this is a long shot but is there anything I can do so if it contains an attachment it will show the text but ignore the attachment?
Output:
0. Exit
1. Switch User
2. Compose email
3. Read email
4. Change Details
5. Add user
6. Remove User
3
Number of emails: 1
Email Number: 1
Subject:
From: XXXX XXXX
Text:
test
Exit
Switch User
Compose email
Read email
Change Details
Add user
Remove User
3
Number of emails: 0
Exit
Switch User
Compose email
Read email
Change Details
Add user
Remove User
this is the code behind the email retrieval:
import javax.mail.internet.*;
import java.util.Properties;
import javax.mail.*;
import java.util.*;
public class CheckingMails {
public static void check(String user,
String password)
{String host = "pop.gmail.com";
String storetype="pop3";
try {
//create properties field
Properties properties = new Properties();
properties.put("mail.pop3.host", host);
properties.put("mail.pop3.port", "995");
properties.put("mail.pop3.starttls.enable", "true");
Session emailSession = Session.getDefaultInstance(properties);
//create the POP3 store object and connect with the pop server
Store store = emailSession.getStore("pop3s");
store.connect(host, user, password);
//create the folder object and open it
Folder emailFolder = store.getFolder("INBOX");
emailFolder.open(Folder.READ_ONLY);
// retrieve the messages from the folder in an array and print it
Message[] messages = emailFolder.getMessages();
System.out.println("Number of emails: " + messages.length);
for (int i = 0, n = messages.length; i < n; i++) {
Message message = messages[i];
System.out.println("---------------------------------");
System.out.println("Email Number: " + (i + 1));
System.out.println("Subject: " + message.getSubject());
System.out.println("From: " + message.getFrom()[0]);
MimeMultipart mmp = (MimeMultipart) message.getContent();
System.out.println("Text: ");
for (int xyz=1; xyz<mmp.getCount(); xyz++) {
System.out.println(mmp.getBodyPart(i).getContent());
}
}
//close the store and folder objects
emailFolder.close(false);
store.close();
} catch (NoSuchProviderException e) {
e.printStackTrace();
} catch (MessagingException e) {
e.printStackTrace();
} catch (Exception e) {
e.printStackTrace();
}
}
public static void main(String[] args) {
String host = "pop.gmail.com";// change accordingly
String mailStoreType = "pop3";
String username = "yourmail#gmail.com";// change accordingly
String password = "*****";// change accordingly
//check(host, mailStoreType, username, password);
}
}
I want to know what is the best way(load quickly the messages from the server) to get messages from one mailbox(e.g: INBOX, OUTBOX). I've found the folder feth() method and getMessages() method but I don't understand what is better between the two methods.
My current code use getMessages() method but it's still slow:
public static void fetch(String Host, String storeType, String user,
String password) {
try {
// create properties field
Properties properties = new Properties();
properties.put("mail.store.protocol", "imaps");
properties.put("mail.imaps.host", Host);
properties.put("mail.imaps.port", "993");
properties.put("mail.imaps.starttls.enable", "true");
Session emailSession = Session.getDefaultInstance(properties);
// emailSession.setDebug(true);
// create the IMAP store object and connect with the imap server
Store store = emailSession.getStore("imaps");
store.connect(Host, user, password);
// create the folder object and open it
Folder emailFolder = store.getFolder("INBOX");
emailFolder.open(Folder.READ_ONLY);
BufferedReader reader = new BufferedReader(new InputStreamReader(
System.in));
// retrieve the messages from the folder in an array and print it
Message[] messages = emailFolder.getMessages();
System.out.println("messages.length---" + messages.length);
for (int i = 0; i < messages.length; i++) {
Message message = messages[i];
System.out.println("---------------------------------");
writePart(message);
String line = reader.readLine();
if ("YES".equals(line)) {
message.writeTo(System.out);
} else if ("QUIT".equals(line)) {
break;
}
}
// close the store and folder objects
emailFolder.close(false);
store.close();
} catch (NoSuchProviderException e) {
e.printStackTrace();
} catch (MessagingException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
} catch (Exception e) {
e.printStackTrace();
}
}
Can someone explain me what's the right and the better way!
The fetch method is use to prefetch message data in bulk. Normally it's used to fetch and cache message metadata, headers, etc. This is useful if you only need to examine a small amount of message metadata to determine whether to process a message.
You can also use the fetch method to fetch and cache the entire content of a message. Unless you are accessing all the content of every message, you don't want to fetch the entire message using the fetch method. When used that way it behaves more like the POP3 protocol except that it fetches multiple messages at once. Obviously caching entire messages can use a lot of memory.
The getMessages method fetches no message data at all. All it does is give you a "handle" through which you can access message data, which will be fetched on demand. If you call the getSubject method, it will fetch the Subject (which is part of the "envelope" metadata). You might want to use the fetch method to prefetch and cache this envelope data to make subsequent operations more efficient. And when you decide you need to read the body or attachments of a message, that data will be fetched at that point.
Perhaps the fetch method should've been named prefetchAndCache. :-)
I am trying to read javamail inbox and perform search. For this, I am fetching the latest 100 messages and then I am iterating through each to see if they have the sender for whom I am searching for. If its matching, I get its content via getContent().
Here is my javamail code snippet:
try {
Properties properties = new Properties();
properties.setProperty("mail.store.protocol", "imap");
properties.put("mail.imaps.starttls.enable", "true");
properties.put("mail.imap.socketFactory.port", "587");
System.setProperty("javax.net.debug", "ssl");
System.out.println("prop " + properties.getProperty("mail.smtp.port"));
Session session = Session.getDefaultInstance(properties, null);
// session.setDebug(true);
Store store = null;
store = session.getStore("imaps");
store.connect("imap.gmail.com", username, password);
Folder inbox;
inbox = store.getFolder("Inbox");
/* Others GMail folders :
* [Gmail]/All Mail This folder contains all of your Gmail messages.
* [Gmail]/Drafts Your drafts.
* [Gmail]/Sent Mail Messages you sent to other people.
* [Gmail]/Spam Messages marked as spam.
* [Gmail]/Starred Starred messages.
* [Gmail]/Trash Messages deleted from Gmail.
*/
inbox.open(Folder.READ_WRITE);
Message msgs[] = inbox.getMessages(inbox.getMessageCount() - lastHistory, inbox.getMessageCount());
System.out.println("MSgs.length " + msgs.length);
ArrayList<Message> aList = new ArrayList<Message>();
appendTextToConsole("Searching for appropriate messages!!");
for (int ii = msgs.length - 1; ii >= 0; ii--) {
Message msg = msgs[ii];
Address[] in = msg.getFrom();
String sender = InternetAddress.toString(in);
System.out.println((++index) + "Sender: " + sender);
boolean read = msg.isSet(Flags.Flag.SEEN);
if (sender.contains(googleId) && !read) {
//This line below gives FolderClosedException sporadically
Object content = msg.getContent();
if (content instanceof Multipart) {
Multipart mp = (Multipart) content;
for (int i = 0; i < mp.getCount(); i++) {
BodyPart bp = mp.getBodyPart(i);
if (Pattern
.compile(Pattern.quote("text/html"),
Pattern.CASE_INSENSITIVE)
.matcher(bp.getContentType()).find()) {
// found html part
String html = (String) bp.getContent();
Element element = Jsoup.parse(html);
List<Element> anchors = element.getElementsByTag("a");
for (Element e : anchors) {
if (e.attr("href").startsWith("https://www.google.com/url?rct=j&sa=t&url=")
&& !e.attr("style").equalsIgnoreCase("text-decoration:none")) {
String url = e.attr("href");
String title = e.text();
String agency = e.parent().parent().child(1).child(0).child(0).text();
String message = e.parent().parent().child(1).child(0).child(1).text();
String flagUrl = e.parent().parent().child(1).child(1).child(0).child(0).child(3).child(0).attr("href");
System.out.println("URL: " + url);
System.out.println("Title: " + title);
System.out.println("agency: " + agency);
System.out.println("Message: " + message);
System.out.println("flagURL: " + flagUrl);
AbstractMessage ams = new AbstractMessage(url, title, agency, message, flagUrl);
aMsgs.add(ams);
}
}
//System.out.println((String) bp.getContent());
} else {
// some other bodypart...
}
}
try {
inbox.close(true);
} catch (Exception e) {
e.printStackTrace();
}
}
}
}
appendTextToConsole("Done searching for appropriate messages!!");
} catch (Exception mex) {
appendTextToConsole(mex.getMessage());
mex.printStackTrace();
}
But the most irritating thing is that after fetching a few messages, sporadically a javax.mail.FolderClosedException is thrown due to unknown reasons. Now my question is that how do I deal with this scenario? And how do ideal mail clients made using javamail deal with it?
Turn on session debugging and you might get more clues as to what's going on.
Note that the server will close the connection if you're not using it.
And of course all sorts of network failures are possible.
I am trying to access my gmail account and retrieve the information of all unread emails from that.
I have written my code after referring many links. I am giving a few links for reference.
Send & Receive emails through a GMail account using Java
Java Code to Receive Mail using JavaMailAPI
To test my code, I created one Gmail account. So I received 4 messages in that from Gmail.
I run my application after checking number of mails. That showed correct result. 4 unread mails.
All the infomation was being displayed (e.g. date, sender, content, subject, etc.)
Then I logged in to my new account, read one of the emails and rerun my application.
Now the count of unread message should have been 3, but it displays "No. of Unread Messages : 0"
I am copying the code here.
public class MailReader
{
Folder inbox;
// Constructor of the calss.
public MailReader() {
System.out.println("Inside MailReader()...");
final String SSL_FACTORY = "javax.net.ssl.SSLSocketFactory";
/* Set the mail properties */
Properties props = System.getProperties();
// Set manual Properties
props.setProperty("mail.pop3.socketFactory.class", SSL_FACTORY);
props.setProperty("mail.pop3.socketFactory.fallback", "false");
props.setProperty("mail.pop3.port", "995");
props.setProperty("mail.pop3.socketFactory.port", "995");
props.put("mail.pop3.host", "pop.gmail.com");
try
{
/* Create the session and get the store for read the mail. */
Session session = Session.getDefaultInstance(
System.getProperties(), null);
Store store = session.getStore("pop3");
store.connect("pop.gmail.com", 995, "abc#gmail.com",
"paasword");
/* Mention the folder name which you want to read. */
// inbox = store.getDefaultFolder();
// inbox = inbox.getFolder("INBOX");
inbox = store.getFolder("INBOX");
/* Open the inbox using store. */
inbox.open(Folder.READ_ONLY);
/* Get the messages which is unread in the Inbox */
Message messages[] = inbox.search(new FlagTerm(new Flags(
Flags.Flag.SEEN), false));
System.out.println("No. of Unread Messages : " + messages.length);
/* Use a suitable FetchProfile */
FetchProfile fp = new FetchProfile();
fp.add(FetchProfile.Item.ENVELOPE);
fp.add(FetchProfile.Item.CONTENT_INFO);
inbox.fetch(messages, fp);
try
{
printAllMessages(messages);
inbox.close(true);
store.close();
}
catch (Exception ex)
{
System.out.println("Exception arise at the time of read mail");
ex.printStackTrace();
}
}
catch (MessagingException e)
{
System.out.println("Exception while connecting to server: "
+ e.getLocalizedMessage());
e.printStackTrace();
System.exit(2);
}
}
public void printAllMessages(Message[] msgs) throws Exception
{
for (int i = 0; i < msgs.length; i++)
{
System.out.println("MESSAGE #" + (i + 1) + ":");
printEnvelope(msgs[i]);
}
}
public void printEnvelope(Message message) throws Exception
{
Address[] a;
// FROM
if ((a = message.getFrom()) != null) {
for (int j = 0; j < a.length; j++) {
System.out.println("FROM: " + a[j].toString());
}
}
// TO
if ((a = message.getRecipients(Message.RecipientType.TO)) != null) {
for (int j = 0; j < a.length; j++) {
System.out.println("TO: " + a[j].toString());
}
}
String subject = message.getSubject();
Date receivedDate = message.getReceivedDate();
Date sentDate = message.getSentDate(); // receivedDate is returning
// null. So used getSentDate()
String content = message.getContent().toString();
System.out.println("Subject : " + subject);
if (receivedDate != null) {
System.out.println("Received Date : " + receivedDate.toString());
}
System.out.println("Sent Date : " + sentDate.toString());
System.out.println("Content : " + content);
getContent(message);
}
public void getContent(Message msg)
{
try {
String contentType = msg.getContentType();
System.out.println("Content Type : " + contentType);
Multipart mp = (Multipart) msg.getContent();
int count = mp.getCount();
for (int i = 0; i < count; i++) {
dumpPart(mp.getBodyPart(i));
}
} catch (Exception ex) {
System.out.println("Exception arise at get Content");
ex.printStackTrace();
}
}
public void dumpPart(Part p) throws Exception {
// Dump input stream ..
InputStream is = p.getInputStream();
// If "is" is not already buffered, wrap a BufferedInputStream
// around it.
if (!(is instanceof BufferedInputStream)) {
is = new BufferedInputStream(is);
}
int c;
System.out.println("Message : ");
while ((c = is.read()) != -1) {
System.out.write(c);
}
}
public static void main(String args[]) {
new MailReader();
}
}
I searched on google, but I found that you should use Flags.Flag.SEEN to read unread emails.
But thats not showing correct results in my case.
Can someone point out where I might be doing some mistake?
If you need whole code, I can edit my post.
Note: I edited my question to include whole code instead of snippet I had posted earlier.
Your code should work. You can also use the Folder.getUnreadMessageCount() method if all you want is the count.
JavaMail can only tell you what Gmail tells it. Perhaps Gmail thinks that all those messages have been read? Perhaps the Gmail web interface is marking those messages read? Perhaps you have another application monitoring the folder for new messages?
Try reading an unread message with JavaMail and see if the count changes.
You might find it useful to turn on session debugging so you can see the actual IMAP responses that Gmail is returning; see the JavaMail FAQ.
You cannot fetch unread messages with POP3. From JavaMail API:
POP3 supports no permanent flags (see Folder.getPermanentFlags()). In
particular, the Flags.Flag.RECENT flag will never be set for POP3
messages. It's up to the application to determine which messages in a
POP3 mailbox are "new".
You can use IMAP protocol and use the SEEN flag like this:
public Message[] fetchMessages(String host, String user, String password, boolean read) {
Properties properties = new Properties();
properties.put("mail.store.protocol", "imaps");
Session emailSession = Session.getDefaultInstance(properties);
Store store = emailSession.getStore();
store.connect(host, user, password);
Folder emailFolder = store.getFolder("INBOX");
// use READ_ONLY if you don't wish the messages
// to be marked as read after retrieving its content
emailFolder.open(Folder.READ_WRITE);
// search for all "unseen" messages
Flags seen = new Flags(Flags.Flag.SEEN);
FlagTerm unseenFlagTerm = new FlagTerm(seen, read);
return emailFolder.search(unseenFlagTerm);
}
Another thing to notice is that POP3 doesn't handle folders. IMAP gets folders, POP3 only gets the Inbox. More info at: How to retrieve gmail sub-folders/labels using POP3?
Change inbox.open(Folder.READ_ONLY); to inbox.open(Folder.READ_WRITE);
It will change your mail as read in inbox.
Flags seen = new Flags(Flags.Flag.RECENT);
FlagTerm unseenFlagTerm = new FlagTerm(seen, false);
messages = inbox.search(unseenFlagTerm);
The correct flag to use is
Flags.Flag.RECENT
please use this method to get the unread mails
getNewMessageCount()
refer below link:
https://javamail.java.net/nonav/docs/api/com/sun/mail/imap/IMAPFolder.html