2012-05-04 36 views
22

我想實現一個Java郵件servlet,第一步是連接到IMAP服務器。Java郵件到Exchange Server「沒有登錄方法支持」

我可以telnet到端口143(默認的IMAP端口)的客戶端,Telnet說:OK The Microsoft Exchange IMAP4 service is ready.

現在我嘗試連接到使用Java郵件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!; 

編輯:

我加入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 

假設這是一個證書的問題我也跟着these instructions並添加郵件服務器到我的cacerts文件。測試程序包含在那裏運行完全正常,我可以使用SSL URL連接,但運行Java郵件類時仍然有相同的異常。

我也嘗試更改爲「imaps」:session.getStore("imaps")(而不是「imap」),甚至無法獲得「Microsoft Exchange Server現在已準備就緒」消息。我認爲,因爲它試圖在指定「imaps」時嘗試在端口993上進行連接。但是使用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 Server上啓用?

我沒有到電子郵件服務器隨時訪問,但我可能會找人來讓我在

解決方案:

低於他的答案HulkingUnicorn的評論指出this answer這是需要的確切處理。顯然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"); 

回答

17

這部分,* CAPABILITY IMAP4 IMAP4rev1 LOGINDISABLED 建議您無法登錄,在this thread的OP通過更新他的Javamail到1.4.4來解決它(儘管你的調試輸出表明你已經有了)。嘗試使用1.4.5.

其實,在創建會話之前嘗試添加此行;你的電子郵件服務器支持它,默認情況下它是禁用的: props.put("mail.imap.starttls.enable", "true");

This answer解決了這個問題。

+0

我嘗試了這個和更多的東西,但沒有運氣呢。 – Geronimo

+1

如果你使用「imaps」,你必須在所有屬性中加上's',比如'prop.setProperty(「mail.imaps.port」,「143」);'看起來不太可能服務器儘管使用該端口號使用imaps。 – HulkingUnicorn

+0

@ Geronimo您是否嘗試過Javamail 1.4.5? – HulkingUnicorn

5

您可以使用屬於javamail 1.4.5 API的com.sun.mail.util.MailSSLSocketFactory

例子:

MailSSLSocketFactory sf = new MailSSLSocketFactory(); 
sf.setTrustAllHosts(true); 
props.put("mail.imap.starttls.enable", "true"); 
props.put("mail.imap.ssl.socketFactory", sf); 

沒有必要使用自定義SSLSocketFactory的。

+0

太棒了!你救了我的一天 – 2016-02-11 11:37:58