Javamail 接收icloud邮件

最近在做一个邮件拨测项目,服务端运行一个job,每隔一段时间向程序设定的目标邮箱发送批量测试邮件,使用 javamail sdk 拉取邮件,统计到达率,一旦出现到达率低的情况立即报警。

由于目标邮箱供应商众多,且用户多来自海外,在测试连接邮箱的时候遇到诸多问题。这里主要分享一下配合读取icloud邮箱是遇到的问题。

先上代码

//读取邮件,新建ReceiveEmailTool类
public static List getEmailList(String protocol, String username, String password, String host,
        String deleteFlag, String socksProxyHost, String socksProxyPort) {
        
        //要读取的邮件都在此文件夹下,不管已读未读
        String foldName = "INBOX";
        
        //SSL_FACTORY 
        String SSL_FACTORY = "javax.net.ssl.SSLSocketFactory";
        List list = new ArrayList<>();
        try {
            Properties props = System.getProperties();

            //设置代理
            props.setProperty("proxySet", "true");
            props.setProperty("socksProxyHost", socksProxyHost);
            props.setProperty("socksProxyPort", socksProxyPort);

            //协议,pop3或imap
            props.setProperty("mail.store.protocol", protocol);

            if (protocol.equals("pop3")) {
                props.setProperty("mail.pop3.host", host);
                props.setProperty("mail.pop3.port", "995");
                props.setProperty("mail.pop3.auth", "true");
                props.setProperty("mail.pop3.ssl.enable", "true");
                props.setProperty("mail.pop3.socketFactory.port", "995");
                props.setProperty("mail.pop3.socketFactory.fallback", "false");
                props.setProperty("mail.pop3.socketFactory.class", SSL_FACTORY);
            } else {
                props.setProperty("mail.imap.host", host);
                props.setProperty("mail.imap.port", "993");
                props.setProperty("mail.imap.auth", "true");
                props.setProperty("mail.imap.ssl.enable", "true");
                props.setProperty("mail.imap.socketFactory.port", "993");
                props.setProperty("mail.imap.socketFactory.fallback", "false");
                props.setProperty("mail.imap.socketFactory.class", SSL_FACTORY);
            }

            // 获取连接
            Session session = Session.getDefaultInstance(props);
            session.setDebug(false);

            // 获取Store对象
            Store store = session.getStore(protocol);
            store.connect(username, password);

            Folder folder = store.getFolder(foldName);
            folder.open(Folder.READ_WRITE); // 设置对邮件帐户的访问权限

            Message[] messages = folder.getMessages();// 得到邮箱帐户中的所有邮件
            for (Message message : messages) {
                EmailEntity en = new EmailEntity();
                en.setSubject(message.getSubject());// 获得主题
                if (deleteFlag.equals("true")) {
                    message.setFlag(Flags.Flag.DELETED, true);//标记删除
                }
                list.add(en);
            }

            folder.close(true);// 关闭邮件夹对象,删除已标记的邮件,注意是彻底删除
            store.close(); // 关闭连接对象
        } catch (Throwable e) {     
            System.out.println(e.getMessage());
        }
        return list;
    }

测试

public static void main(String[] args) {
        String protocol = "imap";//icloud 邮箱只支持imap协议
        String host = "imap.mail.me.com";//icloud 邮件服务器
        String username = "youricloud";//填写@icloud.com前面的部分即可
        String password = "xxxx-xxxx-xxxx-xxxx";//设置的第三方专用密码,参见:https://support.apple.com/zh-cn/HT202304
        String deleteFlag = "false";// 是否标记删除
        //公司环境必须走代理才能访问邮箱服务器
        String socksProxyHost = "代理host";
        String socksProxyPort = "代理端口";

        List list = ReceiveEmailTool.getEmailList(protocol, username, password, host, deleteFlag, socksProxyHost, socksProxyPort);
        for(EmailEntity en:list){
            System.out.println("主题:" + en.getSubject());
        }
    }

以上代码分别验证通过了hotmail、naver、qq、outlook、163 等邮箱,使用的是pop3协议。但是因为icloud不支持pop3,所以走imap协议。运行上述代码,控制台报错输出:Authentication failed for ORACLE User。

解决方案:

最终在谷歌上搜到了一个类似的案例:How to use Javamail for accessing additional mailboxes (IMAP, Exchange 2010)

properties = System.getProperties();
properties.setProperty("mail.imaps.auth.plain.disable", "true");
properties.setProperty("mail.imaps.auth.ntlm.disable", "true");
Session session = Session.getInstance(properties, null);
store = session.getStore("imaps");
store.connect("HOST", PORT, "DOMAIN\\USER\\SHAREDACCOUNT","pwd");

于是我尝试着在代码里加上这两行,果然有效

props.setProperty("mail.imap.auth.plain.disable", "true");
props.setProperty("mail.imap.auth.ntlm.disable", "true");

查看一下这两个属性的意思,如果设置为true,则阻止AUTHENTICATE PLAIN 和 AUTHENTICATE NTLM 命令。默认为false。

你可能感兴趣的:(Javamail 接收icloud邮件)