Java 通过独立应用程序轮询GMail收件箱接收邮件的正确方法
我正在尝试在GMail收件箱中查询收到的邮件。以下是我所拥有的:Java 通过独立应用程序轮询GMail收件箱接收邮件的正确方法,java,email,gmail,jakarta-mail,polling,Java,Email,Gmail,Jakarta Mail,Polling,我正在尝试在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.Ses
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();
}
}
}
我想知道这是否是一种正确的方法,或者是否有其他更好的方法。您可能需要修复这些问题,并且需要连接到imap服务器,而不是smtp服务器(请参阅)。否则,你就有了正确的总体思路。你可能想看看这个
您可能还希望在使用连接时处理更多的错误情况。只要您的服务器支持空闲(gmail会),并且您只希望收到新邮件的通知(因为程序正在运行),下面的程序就应该适合您的需要。如果服务器不支持空闲和/或旧消息相关(或文件夹重命名等其他事件),则需要修改代码。在这里查看一些提示:
我不太了解这个主题,但谷歌有一个应用程序引擎API,不使用上面提到的IMAP,你可以在这里找到更多信息:@LexWebb谢谢,但我没有使用应用程序引擎,我的应用程序是独立的。我使用的是你提供的代码。我在方法
run()
中放置了两个日志。一个在while
内,另一个在while
后。现在我只能在中看到日志一次。另外,当我从外部调用您的kill()
方法时,我看不到我在while
之后放置的日志?你知道发生了什么事吗?感谢您分享您的工作。当idle()方法返回时(取决于服务器和邮箱活动),您将看到更多日志语句。如果你想强制这个视图。如果你调用Kyle(),然后(例如)文件夹。Couter()你已经完成了。@ Salh Hi,我在哪里可以找到关于这个资源的C++或Objtovi-C的一些信息?@ SaLyh你使用了哪种版本的JavaX.mail?尝试1.4和IMAPFolder.idle()方法是非常困难的missing@freitas1.6.1应具有空闲方法。
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());
}
}
}