我编写了代码,每小时检查是否有来自特定发件人的带有附件的新电子邮件。预计每小时都会收到来自特定用户的带有附件的电子邮件(因此不使用空闲功能)。
检测到新电子邮件时,来自该用户的所有新电子邮件都会保存到数组中,并检查最新电子邮件中的 csv 附件、进行操作并保存到磁盘。
检查新电子邮件的代码看起来非常冗长,我想知道是否可以进行任何改进。
具体来说,(1) 如果用户登录并阅读和发送电子邮件,则比较调用之间的未读消息计数将会失败。
(2) 新电子邮件数组仅查看最新电子邮件 (length()-1)。
public class Mail implements Runnable {
private static final long KEEP_ALIVE_FREQ = 3000; // time between mail checks
@Override
public void run() {
String host = "imap.gmail.com";
String username = "user@gmail.com";
String password = "passwd";
Properties props = new Properties();
props.setProperty("mail.imap.ssl.enable", "true");
Folder inbox;
int messageCount;
Store store = null;
Session session = Session.getInstance(props);
try {
store = session.getStore("imap");
store.connect(host,username,password);
inbox = store.getFolder("inbox");
inbox.open(Folder.READ_WRITE);
messageCount = inbox.getUnreadMessageCount();
inbox.close(true);
while (!Thread.interrupted()) {
inbox.open(Folder.READ_WRITE);
try {
if (inbox.getUnreadMessageCount() > messageCount) {
System.out.println("New mail has arrived");
// Construct array of unseen messages from specified user
FlagTerm unseenFlagTerm = new FlagTerm(new Flags(Flags.Flag.SEEN), false);
FromTerm senderFlagTerm = new FromTerm(new InternetAddress("specifieduser@gmail.com"));
SearchTerm searchTerm = new AndTerm(unseenFlagTerm, senderFlagTerm);
Message messages[] = inbox.search(searchTerm);
// check that messages array contains at least one message from senderFlag
if (messages.length>0) {
Message msg = messages[messages.length - 1]; // get most recent message from sender
if (hasAttachments(msg)) {
System.out.println("Message has an attachment - processing");
String csv = attachmentToString(msg);
String cleanCsv = cleanCsv(csv);
FileUtils.writeStringToFile(new File("C:\\tmp\\somefile.csv"), cleanCsv, StandardCharsets.UTF_8, false);
// delete message
msg.setFlag(Flags.Flag.DELETED, true);
}
}
}
} catch (IOException e) {
e.printStackTrace();
}
// reset unread message count
messageCount = inbox.getUnreadMessageCount();
// close inbox
inbox.close(true);
System.out.println("About to sleep");
Thread.sleep(KEEP_ALIVE_FREQ);
}
} catch (NoSuchProviderException e) {
e.printStackTrace();
} catch (MessagingException e) {
e.printStackTrace();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
public String attachmentToString(Message message) throws IOException, MessagingException {
Multipart multipart = (Multipart) message.getContent();
String theString = null;
for (int i = 0; i < multipart.getCount(); i++) {
BodyPart bodyPart = multipart.getBodyPart(i);
if (!Part.ATTACHMENT.equalsIgnoreCase(bodyPart.getDisposition()) &&
StringUtils.isBlank(bodyPart.getFileName())) {
continue; // dealing with attachments only
}
InputStream inputStream = bodyPart.getInputStream();
StringWriter writer = new StringWriter();
IOUtils.copy(inputStream, writer, "UTF-8");
theString = writer.toString();
}
return theString;
}
public String cleanCsv(String csv) {
csv = csv.replaceAll("\"", "");
csv = csv.replaceAll("\\s*,", ",");
return csv;
}
boolean hasAttachments(Message msg) throws MessagingException, IOException {
if (msg.isMimeType("multipart/mixed")) {
Multipart mp = (Multipart)msg.getContent();
if (mp.getCount() > 1)
return true;
}
return false;
}
}
因为我知道电子邮件总是在整点+/-一分钟左右到达 - 安排邮件检查的代码会更简单并且更可靠吗?
最佳答案
正如 @arnt 所说,跟踪最后处理的消息的 UID,然后搜索符合您条件的新消息:
FromTerm senderFromTerm = new FromTerm(new InternetAddress("specifieduser@gmail.com"));
// first, find all the new messages since we last looked
Message messages[] = ((UIDFolder)inbox).getMessagesByUID(lastProcessedUID, UIDFolder.LASTUID);
// now search within the new messages for those from our user
messages = inbox.search(senderFromTerm, messages);
关于Java Mail - 检查来自特定发件人的带有附件的新邮件,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/51346197/