Abrufen von E-Mails von GMail in eine Java-Anwendung mithilfe von IMAP

76

Ich möchte mit JavaMail und IMAP von einer Java-Anwendung aus auf Nachrichten in Google Mail zugreifen . Warum erhalte ich eine SocketTimeoutException ?

Hier ist mein Code:

Properties props = System.getProperties();
props.setProperty("mail.imap.host", "imap.gmail.com");
props.setProperty("mail.imap.port", "993");
props.setProperty("mail.imap.connectiontimeout", "5000");
props.setProperty("mail.imap.timeout", "5000");

try {
    Session session = Session.getDefaultInstance(props, new MyAuthenticator());
    URLName urlName = new URLName("imap://[email protected]:[email protected]");
    Store store = session.getStore(urlName);
    if (!store.isConnected()) {
        store.connect();
    }
} catch (NoSuchProviderException e) {
    e.printStackTrace();
    System.exit(1);
} catch (MessagingException e) {
    e.printStackTrace();
    System.exit(2);
}

Ich habe die Timeout-Werte so eingestellt, dass das Timeout nicht "ewig" dauert. Außerdem verfügt MyAuthenticator über den Benutzernamen und das Kennwort, die mit der URL überflüssig zu sein scheinen. Gibt es eine andere Möglichkeit, das Protokoll anzugeben? (Ich habe es im JavaDoc für IMAP nicht gesehen .)

Dave
quelle
1
Wenn Sie mit JavaMail auf GMail-Threads zugreifen möchten, interessieren Sie sich möglicherweise für code.google.com/p/java-gmail-imap
Mark McLaren
2
Funktioniert eine dieser IMAP-basierten Lösungen nicht mehr, ohne dass weniger sichere Apps zugelassen werden müssen?
Jordanpg
Siehe auch

Antworten:

70

Die Verwendung von Imaps war ein großartiger Vorschlag. Keine der Antworten funktionierte nur für mich, also googelte ich noch etwas und fand etwas, das funktionierte. So sieht mein Code jetzt aus.

Properties props = System.getProperties();
props.setProperty("mail.store.protocol", "imaps");
try {
  Session session = Session.getDefaultInstance(props, null);
  Store store = session.getStore("imaps");
  store.connect("imap.gmail.com", "<username>@gmail.com", "<password>");
  ...
} catch (NoSuchProviderException e) {
  e.printStackTrace();
  System.exit(1);
} catch (MessagingException e) {
  e.printStackTrace();
  System.exit(2);
}

Das ist schön, weil es den redundanten Authenticator aus dem Bild nimmt. Ich bin froh, dass dies funktioniert hat, weil die SSLNOTES.txt mir den Kopf verdreht.

Dave
quelle
8

Sie müssen die folgenden Eigenschaften für Imaps verwenden:

props.setProperty("mail.imaps.host", "imap.gmail.com");
props.setProperty("mail.imaps.port", "993");
props.setProperty("mail.imaps.connectiontimeout", "5000");
props.setProperty("mail.imaps.timeout", "5000");

Beachten Sie, dass es sich um "imaps" und nicht um "imap" handelt, da das von Ihnen verwendete Protokoll imaps (IMAP + SSL) ist.

WhyNotHugo
quelle
6

In JavaMail können Sie imapsIMAP über SSL als URL-Schema verwenden. ( SSLNOTES.txtWeitere Informationen finden Sie in Ihrer JavaMail-Distribution.) Zum Beispiel imaps://username%[email protected]/INBOX.

Verwenden Sie smtpsin ähnlicher Weise E-Mails über Google Mail. zB , smtps://username%[email protected]/. Lesen Sie noch einmal SSLNOTES.txtfür weitere Details. Ich hoffe es hilft!

Chris Jester-Young
quelle
3

Sie müssen nur über SSL eine Verbindung zu GMail herstellen. Wenn Sie die folgenden Eigenschaften festlegen, wird dies für Sie erzwungen.

props.setProperty ("mail.imap.socketFactory.class", "javax.net.ssl.SSLSocketFactory");
props.setProperty ("mail.imap.socketFactory.fallback", "false");
Brian Matthews
quelle
Ich empfehle diesen Ansatz im Allgemeinen nicht, da er alle IMAP-Verbindungen als IMAP überschreibt. Manchmal ist die Auswahl eine gute Sache, insbesondere wenn das Programm nur für die Verbindung mit Google Mail verwendet werden soll. Wenn Sie jedoch der Meinung sind, dass einfaches IMAP völlig falsch ist, ist dieser Ansatz akzeptabel. :-)
Chris Jester-Young
... meinte, um mehr als nur eine Verbindung zu Google Mail herzustellen . :-P
Chris Jester-Young
2

Wenn Sie mehr Beispielcode für die Verwendung von JavaMail mit Google Mail wünschen (z. B. das Konvertieren von Google Mail-Labels in IMAP-Ordnernamen oder die Verwendung von IMAP IDLE), lesen Sie mein Programm GmailAssistant auf SourceForge .

Zach Scrivena
quelle
2

Folgendes hat für mein Team und mich unter Berücksichtigung eines klassischen Kontos mit dem Spitznamen @gmail.com und eines Geschäftskontos [email protected] funktioniert:

            final Properties properties = new Properties();
            properties.put("mail.imap.ssl.enable", "true");

            imapSession = Session.getInstance(properties, null);
            imapSession.setDebug(false);
            imapStore = imapSession.getStore("imap");

            imapStore.connect("imap.gmail.com", USERNAME, "password");

mit USERNAME = "Spitzname" im klassischen Fall und USERNAME = "[email protected]" im Fall des Geschäftskontos.

Vergessen Sie im klassischen Fall und wenn Sie eine alte JavaMail-Abhängigkeit verwenden, die Kontosicherheit hier nicht zu verringern: https://www.google.com/settings/security/lesssecureapps

Überprüfen Sie in beiden Fällen unter GMail- Einstellungen => POP / IMAP weiterleiten, ob IMAP für das Konto aktiviert ist.

Ich hoffe es hilft!

Um weiter zu gehen:

lboix
quelle
Was meinst du mit "alter JavaMail-Abhängigkeit"? Ich glaube nicht, dass dies etwas mit der JavaMail-Version zu tun hat. Sie verbinden sich mit IMAPS anstelle von OAUTH2.
Jordanpg
1

Ich habe die folgenden Eigenschaften verwendet, um das Geschäft zu erhalten, und es funktioniert gut.

"mail.imaps.host" : "imap.gmail.com"
"mail.store.protocol" : "imaps"
"mail.imaps.port" : "993"

Alex Cheng
quelle
0

Sie müssen JSSE installiert haben, um SSL mit Java verwenden zu können

hd1
quelle
0
URLName server = new URLName("imaps://<gmail-user-name>:<gmail-pass>@imap.gmail.com/INBOX");
Nishanthi Grashia
quelle