从独立应用程序轮询GMail收件箱以接收传入邮件的正确方法

我正在尝试为收到的邮件调查GMail收件箱。 这是我有的:

import java.util.Properties; import javax.mail.Authenticator; import javax.mail.Folder; import javax.mail.Message; import javax.mail.MessagingException; import javax.mail.PasswordAuthentication; import javax.mail.Session; import javax.mail.event.MessageCountEvent; import javax.mail.event.MessageCountListener; import com.sun.mail.imap.IMAPFolder; import com.sun.mail.imap.IMAPStore; public class GmailIncomingTest { public static void main(String[] args) { try { String username = "my.user@gmail.com"; String password = "mypassword"; Properties properties = new Properties(); properties.put("mail.smtp.auth", "true"); properties.put("mail.smtp.host", "smtp.gmail.com"); properties.put("mail.smtp.port", "587"); Session session = Session.getDefaultInstance(properties, new Authenticator() { protected PasswordAuthentication getPasswordAuthentication() { return new PasswordAuthentication(username, password); } }); IMAPStore store = (IMAPStore) session.getStore("imaps"); store.connect("smtp.gmail.com", username, password); IMAPFolder inbox = (IMAPFolder) store.getFolder("inbox"); inbox.open(Folder.READ_ONLY); inbox.addMessageCountListener(new MessageCountListener() { @Override public void messagesRemoved(MessageCountEvent event) { } @Override public void messagesAdded(MessageCountEvent event) { Message[] messages = event.getMessages(); for (Message message : messages) { try { System.out.println("Mail Subject:- " + message.getSubject()); } catch (MessagingException e) { e.printStackTrace(); } } } }); new Thread(new Runnable() { private static final long KEEP_ALIVE_FREQ = 10000; @Override public void run() { while (!Thread.interrupted()) { try { inbox.idle(); Thread.sleep(KEEP_ALIVE_FREQ); } catch (InterruptedException e) { } catch (MessagingException e) { } } } }).start(); } catch (Exception e) { e.printStackTrace(); } } } 

我想知道这是否是一种正确的方法,或者是否还有其他更好的方法。

只要您的服务器支持IDLE(gmail将)并且您只想通知新邮件(因为程序正在运行),而下面的程序应该满足您的需求。 如果服务器不支持IDLE和/或旧消息相关(或其他事件,如文件夹重命名等),则需要修改代码。 看看这里有一些提示: https : //github.com/salyh/elasticsearch-imap/blob/master/src/main/java/de/saly/elasticsearch/importer/imap/mailsource/ParallelPollingIMAPMailSource.java

 import java.util.Properties; import javax.mail.Folder; import javax.mail.Message; import javax.mail.MessagingException; import javax.mail.Session; import javax.mail.Store; import javax.mail.event.MessageCountAdapter; import javax.mail.event.MessageCountEvent; import com.sun.mail.imap.IMAPFolder; import com.sun.mail.imap.IMAPStore; public class GmailIncomingTest { private static final String username = "xxx@gmail.com"; private static final String password = "passwd"; public static void main(String[] args) { Properties properties = new Properties(); // properties.put("mail.debug", "true"); properties.put("mail.store.protocol", "imaps"); properties.put("mail.imaps.host", "imap.gmail.com"); properties.put("mail.imaps.port", "993"); properties.put("mail.imaps.timeout", "10000"); Session session = Session.getInstance(properties); // not // getDefaultInstance IMAPStore store = null; Folder inbox = null; try { store = (IMAPStore) session.getStore("imaps"); store.connect(username, password); if (!store.hasCapability("IDLE")) { throw new RuntimeException("IDLE not supported"); } inbox = (IMAPFolder) store.getFolder("INBOX"); inbox.addMessageCountListener(new MessageCountAdapter() { @Override public void messagesAdded(MessageCountEvent event) { Message[] messages = event.getMessages(); for (Message message : messages) { try { System.out.println("Mail Subject:- " + message.getSubject()); } catch (MessagingException e) { e.printStackTrace(); } } } }); IdleThread idleThread = new IdleThread(inbox); idleThread.setDaemon(false); idleThread.start(); idleThread.join(); // idleThread.kill(); //to terminate from another thread } catch (Exception e) { e.printStackTrace(); } finally { close(inbox); close(store); } } private static class IdleThread extends Thread { private final Folder folder; private volatile boolean running = true; public IdleThread(Folder folder) { super(); this.folder = folder; } public synchronized void kill() { if (!running) return; this.running = false; } @Override public void run() { while (running) { try { ensureOpen(folder); System.out.println("enter idle"); ((IMAPFolder) folder).idle(); } catch (Exception e) { // something went wrong // wait and try again e.printStackTrace(); try { Thread.sleep(100); } catch (InterruptedException e1) { // ignore } } } } } public static void close(final Folder folder) { try { if (folder != null && folder.isOpen()) { folder.close(false); } } catch (final Exception e) { // ignore } } public static void close(final Store store) { try { if (store != null && store.isConnected()) { store.close(); } } catch (final Exception e) { // ignore } } public static void ensureOpen(final Folder folder) throws MessagingException { if (folder != null) { Store store = folder.getStore(); if (store != null && !store.isConnected()) { store.connect(username, password); } } else { throw new MessagingException("Unable to open a null folder"); } if (folder.exists() && !folder.isOpen() && (folder.getType() & Folder.HOLDS_MESSAGES) != 0) { System.out.println("open folder " + folder.getFullName()); folder.open(Folder.READ_ONLY); if (!folder.isOpen()) throw new MessagingException("Unable to open folder " + folder.getFullName()); } } } 

您可能想要修复这些常见错误 ,并且需要连接到imap服务器,而不是smtp服务器(请参阅JavaMail FAQ中的GMail示例 )。 否则,你就有了正确的总体思路。 您可能希望查看monitor.java示例程序 。

当您使用连接时连接断开时,您可能还希望处理更多错误情况。