我正在尝试轮询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示例程序。
您可能还想在使用连接时处理更多的错误情况。