JavaMail doesn't download full csv file attachment - java

I am having an issue with downloading csv file attachments from Gmail. All the settings/preferences seem to work fine. The plugin will download most of the file without issue, in fact the program doesn't produce any errors but it is cutting off the last line of the file and partially from the second to last line.
Can anyone see an issue in my code that would point to why this is happening?
Edit: Updated code to reflect for loop changes.
Edit2: Is there an overflow or buffer size I need to be worried about? The size of the files I will be downloading aren't very big. They are csv files with at least 140 lines in them.
public void searchEmailByID (int emailID) {
Properties properties = new Properties();
//server setting
properties.put("mail.imap.host", GmailHost);
properties.put("mail.imap.port", GmailPort);
//SSL setting
properties.setProperty("mail.imap.socketFactory.class", "javax.net.ssl.SSLSocketFactory");
properties.setProperty("mail.imap.socketFactory.fallback", "false");
properties.setProperty("mail.imap.socketFactory.port", String.valueOf(GmailPort));
Session session = Session.getDefaultInstance(properties);
try {
//connects to message store
Store store = session.getStore("imap");
store.connect(GmailUser, GmailPassword);
//opens the inbox folder
Folder folderInbox = store.getFolder("Inbox");
folderInbox.open(Folder.READ_ONLY);
//creates the search criteria
SearchTerm searchCondition = new SearchTerm() {
#Override
public boolean match(Message message) {
try {
if (message.getMessageNumber() == emailID) {
return true;
}
} catch (NullPointerException ex) {
System.out.println("Null exception at line 50, may be due to variation in timing");
//ex.printStackTrace();
}
return false;
}
};
//performs search through the folder
Message[] foundMessages = folderInbox.search(searchCondition);
setRecentlySearchMsg(foundMessages[0]);
for (int i = 0; i < foundMessages.length; i++) {
Message message = foundMessages[i];
String subject = message.getSubject(); //subject in the target email
Date date = message.getReceivedDate(); //date the email was received
System.out.println("Found message #" + i + ": " + subject + ", Date Received: " + date.toString());
String contentType = message.getContentType();
System.out.println("Content type: " + contentType);
Multipart multipart = (Multipart) message.getContent();
int count = 0; //count object to ensure overflows aren't triggered
for (int j = 0; j < multipart.getCount(); j++) {
MimeBodyPart part = (MimeBodyPart) multipart.getBodyPart(j); //using the i loop to establish connection to message
if(part.getContentType().contains("TEXT/PLAIN")) {
continue;
} else if(part.getContentType().contains("TEXT/HTML")) {
break;
}
if (Part.ATTACHMENT.equalsIgnoreCase(part.getDisposition())) {
String dateToday = new SimpleDateFormat("MM-dd-yyyy").format(new Date()); //Retrieving today's date
String path = "/file/location/here/" + dateToday + "_" + part.getFileName();
if(part.getFileName().contains("User")) {
userFileLocation = path;
} else if(part.getFileName().contains("Teams")) {
teamFileLocation = path;
}
part.saveFile(path);
System.out.println("File successfully saved in folder with name: " + path);
System.out.println("File is located at: " + path);
count++;
}
if (count == 2){
break;
}
}
}
//disconnect
folderInbox.close(false);
store.close();
} catch (NoSuchProviderException ex) {
System.out.println("No provider.");
ex.printStackTrace();
} catch (MessagingException ex) {
System.out.println("Could not connect to the message store.");
ex.printStackTrace();
} catch (IOException ex) {
System.out.println("Error parsing message attachment");
ex.printStackTrace();
}
}

Related

Is it possible to fetch mail source data using Java Api [Mail is not saved as a file]

I am able to get mail subject and body contents using Java Api.
But in my application i received a template in an email which contains a url behind an image. I need to get that url, I found that the url was displayed when i view the source for that email manually.
Remember that i am not downloading the email instead i am connecting to mail server and then reading the mail data for any specific user
Is there a way that i can view the source of email like i am getting the subject of mail.
Here is the code:
import org.jsoup.Jsoup;
import javax.mail.*;
import javax.mail.internet.MimeMessage;
import java.io.IOException;
import java.util.Properties;
public class VerifyEmails {
public Message message;
public int i, n;
public String result;
public void check(String host, String user, String password) throws IOException, MessagingException {
Properties properties = new Properties();
properties.put("mail.imap.host", host);
properties.put("mail.imap.user", user);
properties.put("mail.imap.port", "143");
properties.put("mail.imap.starttls.enable", "false");
Session emailSession = Session.getDefaultInstance(properties);
Store store = emailSession.getStore("imap");
System.out.println("test1 " + store);
store.connect(host, user, password);
Folder emailFolder = store.getFolder("INBOX");
emailFolder.open(Folder.READ_ONLY);
Message[] messages = emailFolder.getMessages();
System.out.println("messages.length---" + messages.length);
for (i = 0, n = messages.length; i < n; i++) {
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]);
System.out.println("Email contents are :" + message.getContentType());
System.out.println("Email headers are :" + message.getContent());
}
if (message instanceof MimeMessage) {
MimeMessage m = (MimeMessage) message;
Object contentObject = message.getContent();
if (contentObject instanceof Multipart) {
BodyPart clearTextPart = null;
BodyPart htmlTextPart = null;
Multipart content = (Multipart) contentObject;
int count = content.getCount();
for (int i = 0; i < count; i++) {
BodyPart part = content.getBodyPart(i);
if (part.isMimeType("text/plain")) {
clearTextPart = part;
String test = String.valueOf(clearTextPart.getAllHeaders());
System.out.println("check1" + test);
break;
} else if (part.isMimeType("text/html")) {
htmlTextPart = part;
}
}
if (clearTextPart != null) {
result = (String) clearTextPart.getContent();
String test = String.valueOf(clearTextPart.getAllHeaders());
System.out.println("check2" + test);
System.out.println("plain text: " + result);
} else if (htmlTextPart != null) {
String html = (String) htmlTextPart.getContent();
result = Jsoup.parse(html).text();
System.out.println("html text: " + result);
}
} else if (contentObject instanceof String) // a simple text message
{
result = (String) contentObject;
System.out.println("String text: " + result);
} else // not a mime message
{
result = null;
System.out.println("null : " + result);
}
emailFolder.close(false);
store.close();
}
}
}

Java Mail API: Convert Message to String?

I am using the following code to successfully retrieve messages from my Gmail account.
// Import Statements
public class ConfirmEmail {
WebDriver driver;
Folder inbox;
String gmailID = "xxxxxxxxxxx#gmail.com";
String gmailPass = "xxxxxxxx";
String storeMessage;
public ConfirmEmail()
{
}
public void 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, gmailID,
gmailPass);
/* 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);
}
}
}
With this code I am successfully able to print messages to console. Works flawlessly 100% of the time.
However, I need to store the "bodyPart" (i.e, the actual message or body of message) in a String so I could search the String using Regex. I need to extract links begining with http.
How can I convert the message to a string?
Thanks
I'm not quite sure what you are asking (because you said you already print out your Messages ... so when you print them, why can't you store them in a String?)
if you realy just want the bodyPart stored in a String variable:
Multipart mp = (Multipart) msg.getContent();
BodyPart bp = mp.getBodyPart(0);
String content = bp.getContent().toString();

Retrieve email according to specified date time using POP3 in Java

I got all the mail, but I want to extract mail according to the date.
public void downloadEmailAttachments(String host, String port,String userName, String password) {
Properties properties = new Properties();
properties.put("mail.pop3.host", host);
properties.put("mail.pop3.port", port);
properties.put("mail.pop3.user",userName);
properties.put("mail.password",password);
// SSL setting
properties.setProperty("mail.pop3.socketFactory.class",
"javax.net.ssl.SSLSocketFactory");
properties.setProperty("mail.pop3.socketFactory.fallback", "false");
properties.setProperty("mail.pop3.socketFactory.port",
String.valueOf(port));
Session session = Session.getDefaultInstance(properties);
try {
// connects to the message store
Store store = session.getStore("pop3");
store.connect(host,userName, password);//change here............
Folder folderInbox = store.getFolder("INBOX");
folderInbox.open(Folder.READ_ONLY);
Message[] arrayMessages = folderInbox.getMessages();
for (int i = 0; i < arrayMessages.length; i++) {
Message message = arrayMessages[i];
Address[] fromAddress = message.getFrom();
String from = fromAddress[0].toString();
Address[]toAdress=message.getAllRecipients();
String to=toAdress[0].toString();
String subject = message.getSubject();
String sentDate = message.getSentDate().toString();
String contentType = message.getContentType().toString();
String messageContent = "";
// store attachment file name, separated by comma
String attachFiles = "";
if (contentType.contains("multipart")) {
// content may contain attachments
Multipart multiPart = (Multipart) message.getContent();
int numberOfParts = multiPart.getCount();
for (int partCount = 0; partCount < numberOfParts; partCount++) {
MimeBodyPart part = (MimeBodyPart) multiPart.getBodyPart(partCount);
if (Part.ATTACHMENT.equalsIgnoreCase(part.getDisposition())) {
// this part is attachment
String fileName = part.getFileName();
attachFiles += fileName + ", ";
part.saveFile(saveDirectory + File.separator + fileName);
} else {
// this part may be the message content
messageContent = part.getContent().toString();
}
}
if (attachFiles.length() > 1) {
attachFiles = attachFiles.substring(0, attachFiles.length() - 2);
}
} else if (contentType.contains("text/plain")
|| contentType.contains("text/html")) {
Object content = message.getContent();
if (content != null) {
messageContent = content.toString();
}
}
// print out details of each message
System.out.println("Message #" + (i + 1) + ":");
System.out.println("\t From: " + from);
System.out.println("\t to: " + to);
System.out.println("\t Subject: " + subject);
System.out.println("\t Sent Date: " + sentDate);
System.out.println("\t Message: " + messageContent);
System.out.println("\t Attachments: " + attachFiles);
}
// disconnect...............
folderInbox.close(false);
store.close();
} catch (NoSuchProviderException ex) {
System.out.println("No provider for pop3.");
ex.printStackTrace();
} catch (MessagingException ex) {
System.out.println("Could not connect to the message store");
ex.printStackTrace();
} catch (IOException ex) {
ex.printStackTrace();
}
}
Searching for a period or in general by time is done by the server only if you use IMAP to connect.
Example:
SearchTerm term = null;
Calendar cal = null;
cal = Calendar.getInstance();
Date minDate = new Date(cal.getTimeInMillis()); //get today date
cal.add(Calendar.DAY_OF_MONTH, 1); //add 1 day
Date maxDate = new Date(cal.getTimeInMillis()); //get tomorrow date
ReceivedDateTerm minDateTerm = new ReceivedDateTerm(ComparisonTerm.GE, minDate);
ReceivedDateTerm maxDateTerm = new ReceivedDateTerm(ComparisonTerm.LE, maxDate);
term = new AndTerm(term, minDateTerm); //concat the search terms
term = new AndTerm(term, maxDateTerm);
Message messages[] = folderInbox.search(term); //search on the imap server
If you instead of IMAP use POP3, I guess your only choice is to filter (on the client) on the entire list of messages that you fetched from the server, iterating over it, like #user2310289 was telling you:
for (Message message : messages) {
if (message.getSentDate().after(minDate) && message.getSentDate().before(maxDate))
{
//do whatever you want with your filtered by period message
}
}
I hope I helped you.

Retrieve all emails from gmail several times on android app

This can be silly questions, but....
The code below works perfectly to retrieve all emails from gmail. However, after running the app once, gmail sets "Status: POP is enabled for all mail that has arrived since EXECUTION_APP_TIME" in its "Forwarding and POP/IMAP" settings and the app stops getting the old messages (that makes sense).
I need to get all messages from gmail every time I execute the app, but it only works once. Than I need to change the configuration in "Forwarding and POP/IMAP" to "Enable POP for all mail (even mail that's already been downloaded)" in my gmail after every single execution.
Does anyone know how I could sort it out?
Is there any way to set it automatically through code.
Here is the source code:
public void connect(){
Properties props = new Properties();
props.put("mail.pop3.host" , "pop.gmail.com");
props.put("mail.pop3.user" , username);
// Start SSL connection
props.put("mail.pop3.socketFactory" , 995 );
props.put("mail.pop3.socketFactory.class" , "javax.net.ssl.SSLSocketFactory" );
props.put("mail.pop3.port" , 995);
Log.e("asdasd", "teste");
Session session = Session.getDefaultInstance(props , new Authenticator() {
#Override
protected PasswordAuthentication getPasswordAuthentication() {
return new PasswordAuthentication( username , password);
}
});
try {
Store store = session.getStore("pop3");
store.connect("pop.gmail.com", 995 , username , password);
Folder fldr = store.getFolder("Inbox");
fldr.open(Folder.HOLDS_MESSAGES);
int totalMsg = fldr.getMessageCount();
int unread = fldr.getUnreadMessageCount();
System.out.println("Total MSG: " + totalMsg + " unreaed: " + unread );
Message[] messages = fldr.getMessages();
//Message[] msg = fldr.search(new FlagTerm(new Flags(Flag.SEEN), false));
Message[] msg = messages;
System.out.print("size " + messages .length);
if (messages.length == 0) System.out.println("No messages found.");
for (int i = 0; i < messages.length; i++) {
System.out.println("Subject : " + messages[i].getSubject());
if(messages[i].getSubject().equals("test223")){
System.out.println("Message " + (i + 1));
System.out.println("From : " + messages[i].getFrom()[0]);
System.out.println("Subject : " + messages[i].getSubject());
Object content = messages[i].getContent();
if (content instanceof String)
System.out.print((String)content);
/* text/plain = String
* multipart" = Multipart
* MimeMessage
* input stream = Unknown Data Handler
*/
Multipart multipart = (Multipart) msg[i].getContent();
for (int x = 0; x < multipart.getCount()-1; x++) {
BodyPart bodyPart = multipart.getBodyPart(x);
String disposition = bodyPart.getDisposition();
if (disposition != null && (disposition.equals(BodyPart.ATTACHMENT))) {
System.out.println("Mail have some attachment : ");
DataHandler handler = bodyPart.getDataHandler();
System.out.println("file name : " + handler.getName());
} else {
System.out.println(bodyPart.getContent());
}
}
}
}
fldr.close(true);
store.close();
} catch(Exception exc) {
System.out.println(exc + " error");
}
}

Java FTP file get issue

I have a application that runs as a schedule.It connect to ftp server and get files from remote folder.scheduler runs in every 5min time.Sometimes when there are lot of files in remote location, scheduler runs again while first cycle is running.In such situation some times it download 0 size files even actual file size is greater than 0 in remote location.Does anyone have any idea why this happen?
below is the code to import files.
private void importEDIFiles(String host, String user, String password, String path, String road) {
try {
String edi824Path = path + "/" + EDI_824_FOLDER;
FTPBroker ftpBroker = new FTPBroker(host, user, password, edi824Path);
FTPClient client = ftpBroker.makeFTPConeection();
String os = client.getSystemName();
client.setFileTransferMode(FTP.ASCII_FILE_TYPE);
File edi824File = null;
File edi824Filebak = null;
ArrayList<FTPFile> files;
try {
FTPFile[] ftpfiles = client.listFiles();
logger.info("\t" + ftpfiles.length + " files are in ftp location ");
if (ftpfiles.length > 0) {
files = removeZeroFiles(ftpfiles);
for(int x=0;x<files.size();x++){
logger.info("name ---"+files.get(x).getName());
logger.info("size ----"+files.get(x).getSize());
}
String ftpFile = null;
logger.info("\t" + files.size() + " downloading from " + road + " rail road.");
for (int i = 0; i < files.size(); i++) {
ftpFile = files.get(i).getName();
logger.info("\t" + ftpFile + " is downloading....");
// logger.info("\t" + ftpFile + " size ...." + ftpFile.isEmpty());
String source = destinationFilePath + pathSeparator + road + pathSeparator + ftpFile;
String target = edi_824backupFilePath + pathSeparator + road + pathSeparator + ftpFile;
edi824File = new File(source);
edi824Filebak = new File(target);
FileOutputStream fosout = new FileOutputStream(source);
boolean isRetrieved = client.retrieveFile(ftpFile, fosout);
logger.debug("isRetrieved : " + isRetrieved);
FileUtils.copyFile(edi824File,edi824Filebak);
fosout.flush();
fosout.close();
boolean isDelete = client.deleteFile(ftpFile);
logger.debug("isDelete : " + isDelete);
}
} else {
logger.info("No files to Pull in the FTP Location for " + user);
//throw new RuntimeException("No files to Pull in FTP Location.");
}
} catch (Exception e) {
logger.error(e,e);
e.printStackTrace();
} finally {
client.logout();
client.disconnect();
}
} catch (Exception ex) {
logger.error(ex, ex);
ex.printStackTrace();
}
}
you can use a flag boolean isRunning(), setRunning(boolean ), and synchronize your code so that two or more threads would not run the same method at the same time

Categories

Resources