轮询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 will(,并且你只想收到新邮件的通知(因为程序正在运行(,下面的程序应该符合你的需求。若服务器不支持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常见问题解答中的GMail示例(。否则,你的总体思路是正确的。您可能需要查看monitor.java示例程序。

您可能还想在使用连接时处理更多的错误情况。

相关内容

  • 没有找到相关文章

最新更新