Я пытаюсь реализовать сервлет Java Mail, первый шаг подключается к серверу IMAP.
Я могу подключиться к серверу на сервере 143 (порт IMAP по умолчанию), telnet говорит: OK The Microsoft Exchange IMAP4 service is ready.
Теперь я пытаюсь подключиться к серверу с помощью Java Mail API следующим образом:
Properties props = new Properties();
session = Session.getDefaultInstance(props, null);
store = session.getStore("imap");
store.connect("host","user","password");
И я могу подключиться к этому же серверу с помощью существующего Outlook Webapp с теми же учетными данными, которые я пытаюсь передать ему в java.
Но выполнение этого с помощью session.setDebug(true)
приводит к следующему выводу:
DEBUG: setDebug: JavaMail version 1.4.5
DEBUG: getProvider() returning javax.mail.Provider[STORE,imap,com.sun.mail.imap.IMAPStore,Sun Microsystems, Inc]
DEBUG: mail.imap.fetchsize: 16384
DEBUG: mail.imap.statuscachetimeout: 1000
DEBUG: mail.imap.appendbuffersize: -1
DEBUG: mail.imap.minidletime: 10
DEBUG: trying to connect to host "myHost", port 143, isSSL false
* OK The Microsoft Exchange IMAP4 service is ready.
A0 CAPABILITY
* CAPABILITY IMAP4 IMAP4rev1 LOGINDISABLED STARTTLS UIDPLUS CHILDREN IDLE NAMESPACE LITERAL+
A0 OK CAPABILITY completed.
DEBUG: protocolConnect login, host=myHost, user=myUser, password=<non-null>
javax.mail.MessagingException: No login methods supported!;
EDIT:
Я добавил prop.setProperty("mail.imap.starttls.enable", "true")
, как было предложено.
Однако я начал получать этот отладочный вывод:
DEBUG: setDebug: JavaMail version 1.4.5
DEBUG: getProvider() returning javax.mail.Provider[STORE,imap,com.sun.mail.imap.IMAPStore,Sun Microsystems, Inc]
DEBUG: mail.imap.fetchsize: 16384
DEBUG: mail.imap.statuscachetimeout: 1000
DEBUG: mail.imap.appendbuffersize: -1
DEBUG: mail.imap.minidletime: 10
DEBUG: enable STARTTLS
DEBUG: trying to connect to host "myHost", port 143, isSSL false
* OK The Microsoft Exchange IMAP4 service is ready.
A0 CAPABILITY
* CAPABILITY IMAP4 IMAP4rev1 LOGINDISABLED STARTTLS UIDPLUS CHILDREN IDLE NAMESPACE LITERAL+
A0 OK CAPABILITY completed.
DEBUG: protocolConnect login, host=myHost, user=myUser, password=<non-null>
A1 STARTTLS
A1 OK Begin TLS negotiation now.
DEBUG IMAP: STARTTLS Exception: javax.net.ssl.SSLHandshakeException: sun.security.validator.ValidatorException: PKIX path building failed: sun.security.provider.certpath.SunCertPathBuilderException: unable to find valid certification path to requested target
Предполагая, что это проблема с сертификатом, я следил за этими инструкциями и добавил почтовый сервер в мой файл cacerts. Программа тестирования, включенная в нее, выполнялась полностью нормально, и я мог подключиться с использованием SSL-url, но у меня все еще было то же исключение при запуске java-класса почты.
Я также попытался перейти на "imaps" с помощью session.getStore("imaps")
(вместо "imap" ) и даже не смог получить сообщение "Microsoft Exchange Server теперь готов". Я думаю, потому что он пытается подключиться к порту 993 всякий раз, когда указывается "imaps". Но использование telnet для порта 993 не показывает никакого подключения к серверу электронной почты.
Итак, я попытался заставить программу использовать SSL на порту 143 следующим образом:
// Use SSL
prop.setProperty("mail.imap.socketFactory.class", "javax.net.ssl.SSLSocketFactory");
prop.setProperty("mail.imap.socketFactory.fallback", "false");
// Use port 143
prop.setProperty("mail.imap.port", "143");
prop.setProperty("mail.imap.socketFactory.port", "143");
Только для получения этого исключения, поэтому я не думаю, что он хочет иметь ничего общего с SSL:
DEBUG: mail.imap.fetchsize: 16384
DEBUG: mail.imap.statuscachetimeout: 1000
DEBUG: mail.imap.appendbuffersize: -1
DEBUG: mail.imap.minidletime: 10
DEBUG: trying to connect to host "myHost", port 143, isSSL false
Not able to process the mail reading.
javax.mail.MessagingException: Unrecognized SSL message, plaintext connection?;
Может ли это исключение TLS выше (DEBUG IMAP: STARTTLS Exception: javax.net.ssl.SSLHandshakeException:
) исходить из TLS, который не включен на сервере Exchange?
У меня нет готового доступа к серверу электронной почты, но я мог бы заставить кого-то позволить мне войти.
РЕШЕНИЕ:
Комментарий HulkingUnicorn под его ответом указал этот ответ, который был точной обработкой. Очевидно, что у MS Exchange Server есть эта проблема. Наряду с добавлением класса, указанного в этом ответе на мой пакет, я просто выполнил мои почтовые подключения, как это, и все было хорошо:
Properties prop = new Properties();
prop.setProperty("mail.imap.starttls.enable", "true");
prop.setProperty("ssl.SocketFactory.provider", "my.package.name.ExchangeSSLSocketFactory");
prop.setProperty("mail.imap.socketFactory.class", "my.package.name.ExchangeSSLSocketFactory");
session = Session.getDefaultInstance(prop, null);
session.setDebug(true);
store = session.getStore("imap");
store.connect("myHost","myUser","myPassword");