我正在尝试实现一个 Java Mail servlet,第一步是连接到 IMAP 服务器。
我可以通过端口 143(默认 IMAP 端口)远程登录到服务器,远程登录显示:OK Microsoft Exchange IMAP4 服务已准备就绪。
现在我正在尝试使用 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!;
编辑:
我按照建议添加了 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 邮件类时仍然遇到同样的异常。
我还尝试使用 session.getStore("imaps")
(而不是“imap”)更改为“imaps”,甚至无法获得“Microsoft Exchange Server is now准备好”的消息。我认为是因为只要指定了“imap”,它就会尝试连接端口 993。但是使用 telnet 到端口 993 并没有显示到电子邮件服务器的任何连接。
接下来我尝试强制程序在端口 143 上使用 SSL,如下所示:
// 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:
)是否来自 Exchange Server 上未启用 TLS?
我没有准备好访问电子邮件服务器的权限,但我可以找人让我进入。
解决方案:
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");
最佳答案
这部分,* CAPABILITY IMAP4 IMAP4rev1 LOGINDISABLED
建议您无法登录,在this thread OP 通过将他的 Javamail 更新到 1.4.4 来解决它(尽管您的调试输出表明您已经得到了)。尝试使用 1.4.5.
实际上,在创建 session 之前尝试添加这一行;您的电子邮件服务器支持它,并且默认情况下它被禁用:
props.put("mail.imap.starttls.enable", "true");
This answer解决了问题。
关于Java 邮件到 Exchange 服务器 "no login methods supported",我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/10442877/