Отримання пошти з GMail у додаток Java за допомогою IMAP


76

Я хочу отримувати доступ до повідомлень у Gmail із програми Java за допомогою JavaMail та IMAP . Чому я отримую SocketTimeoutException ?

Ось мій код:

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://MYUSERNAME@gmail.com:MYPASSWORD@imap.gmail.com");
    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);
}

Я встановив значення тайм-ауту, щоб час очікування не тривав "назавжди". Крім того, MyAuthenticator також має ім'я користувача та пароль, які здаються зайвими з URL-адресою. Чи є інший спосіб вказати протокол? (Я не бачив цього в JavaDoc для IMAP .)


1
Якщо ви хочете отримати доступ до потоків GMail за допомогою JavaMail, вас може зацікавити code.google.com/p/java-gmail-imap
Марк Макларен,

2
Чи працює якесь із цих рішень на основі IMAP вже без необхідності "Дозволити менш безпечні програми"?
jordanpg

Відповіді:


70

Використання imaps було чудовою пропозицією. Жодна з наведених відповідей просто не спрацювала для мене, тому я ще погуглив і знайшов щось, що спрацювало. Ось як зараз виглядає мій код.

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);
}

Це приємно, оскільки це видаляє зайвий аутентифікатор із картинки. Я радий, що це спрацювало, тому що SSLNOTES.txt змушує мене крутитися в голові.


8

Вам потрібно використовувати такі властивості для зображень:

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");

Помічає, що це "imaps", а не "imap", оскільки протокол, який ви використовуєте, є imaps (IMAP + SSL)


6

У JavaMail ви можете використовувати imapsяк схему URL-адреси використання IMAP через SSL. (Див SSLNOTES.txtв дистрибутиві JavaMail для отримання більш докладної інформації.) Наприклад, imaps://username%40gmail.com@imap.gmail.com/INBOX.

Так само використовуйте smtpsдля надсилання електронних листів через Gmail. наприклад, smtps://username%40gmail.com@smtp.gmail.com/. Знову ж, читайте SSLNOTES.txtдокладніше. Сподіваюся, це допоможе!


3

Вам потрібно підключитися до GMail лише за допомогою SSL. Встановлення наступних властивостей змусить вас це зробити.

props.setProperty ("mail.imap.socketFactory.class", "javax.net.ssl.SSLSocketFactory");
props.setProperty ("mail.imap.socketFactory.fallback", "false");

Я взагалі не рекомендую такий підхід, оскільки він перевизначає всі з’єднання imap, щоб вони були imaps. Іноді вибір - це добре, особливо якщо програма буде використовуватися для підключення лише до Gmail. Однак, якщо ви вважаєте, що простий IMAP відверто неправильний, тоді такий підхід є прийнятним. :-)
Кріс Джестер-Янг

... я мав на увазі, що використовується для підключення не лише до Gmail. :-P
Кріс Джестер-Янг

2

Якщо ви хочете отримати більше зразка коду щодо використання JavaMail з Gmail (наприклад, перетворення міток Gmail на назви папок IMAP або використання IMAP IDLE), перевірте мою програму GmailAssistant на SourceForge .


2

Ось, що з моєю командою працювало з класичним обліковим записом nickname@gmail.com та бізнес-акаунтом worker@business.com:

            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");

з USERNAME = "псевдонім" у класичному випадку та USERNAME = "worker@business.com" у випадку з бізнес-рахунком.

У класичному випадку, і якщо ви використовуєте стару залежність JavaMail, не забудьте знизити захист облікового запису тут: https://www.google.com/settings/security/lesssecureapps

В обох випадках перевірте Налаштування GMail => Пересилання POP / IMAP, якщо для облікового запису ввімкнено IMAP.

Сподіваюся, це допоможе!

Щоб пройти далі:


Що ви маєте на увазі під "старою залежністю JavaMail"? Я не думаю, що це має щось спільне з версією JavaMail, це те, що ви підключаєтеся до IMAPS замість OAUTH2.
jordanpg


1

Я використовував наступні властивості, щоб отримати магазин, і він працює добре.

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


0

Вам потрібно встановити JSSE, щоб використовувати SSL з Java


Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.