java读取邮件标题时,突然报错Failed to load IMAP envelope

生产环境之前可以正常使用imap协议收取邮件,突然有一天报错Failed to load IMAP envelope,可以确定邮件服务器、账号密码、配置都是正确的,使用foxmail可以正常连接并成功收取邮件,因此可以推测java代码可能有兼容性问题,连接服务器的代码如下,开启mail.debug后,打印日志可以看到已经成功使用imap连接到服务器

    public void connect() throws Exception{
        Properties props = new Properties();
        props.put("mail.host", config.getServer());
        props.put("mail." + config.getProtocol() + ".timeout", 60000);
        props.put("mail." + config.getProtocol() + ".connectiontimeout", 6000);
        props.setProperty("mail.store.protocol", config.getProtocol());
        props.setProperty("mail." + config.getProtocol() + ".host", config.getServer());
        props.setProperty("mail." + config.getProtocol() + ".port", String.valueOf(config.getPort()));

        if(config.isDebug()){
            props.put("mail.debug", "true");
            props.put("mail.debug.auth", "true");
        }
        if(config.isSsl()){
            props.put("mail." + config.getProtocol() + ".socketFactory.port", String.valueOf(config.getPort()));
            props.put("mail." + config.getProtocol() + ".starttls.enable", config.isTtlEnable());
            props.put("mail." + config.getProtocol() + ".ssl.protocols", "TLSv1.2");
            //启用明文验证
            //props .setProperty("mail." + config.getProtocol() + ".auth.plain.disable", "false");

            props.setProperty("mail." + config.getProtocol() + ".socketFactory.fallback","false");
            // 设置授权码验证
            //props.put("mail." + config.getProtocol() + ".auth", "true");
            props.put("mail." + config.getProtocol() + ".ssl.enable", "true");
            props.put("mail." + config.getProtocol() + ".ssl.trust", "*");
            props.put("mail." + config.getProtocol() + ".socketFactory.class", "javax.net.ssl.SSLSocketFactory");
        }
        // 创建Session实例对象
        Session session = Session.getInstance(props);
        // 创建IMAP协议的Store对象

        store = session.getStore(config.getProtocol());
        // 连接邮件服务器
        store.connect(config.getUsername(),config.getPassword());
        // 获得收件箱
        folder = store.getFolder("INBOX");
        // 以只读模式打开收件箱
        folder.open(Folder.READ_ONLY);
    }

mail使用的是1.4.7版本,从服务器读取邮件的代码如下:

    /**
     * 读取cnt封邮件
     */
    public void receiveByCount(int cnt) throws Exception {
        log.info("开始收取邮件");
        long t0 = System.currentTimeMillis();
        cnt--;
        int n = folder.getMessageCount();
        if(n > 0){
            int from = Math.max(1,n - cnt);
            Message[] messages = folder.getMessages(from,n);
            log.info("共收取到{}封邮件",messages.length);
            for (int i = messages.length - 1; i >= 0; i--) {
                log.info("开始读取第{}封邮件",i+1);
                long t = System.currentTimeMillis();
                String uid ;
                if(folder instanceof IMAPFolder){
                    uid = String.valueOf(((IMAPFolder) folder).getUID(messages[i]));
                }else {
                    uid = ((POP3Folder)folder).getUID(messages[i]);
                }
                //这里会报错
                messages[i].getSubject();
                log.info("读取第{}封邮件耗时{}ms",i+1,System.currentTimeMillis()-t);
                //mailList.add(tran);
            }
        }
        log.info("收取邮件结束,耗时{}ms",System.currentTimeMillis()-t0);
    }

 当我调用 messages[i].getSubject(); 时,后台报错Failed to load IMAP envelope,断点找到报错位置

java读取邮件标题时,突然报错Failed to load IMAP envelope_第1张图片

 这里不知为何没有获取到envelope这个对象,网上找到说法说是邮箱服务器设置了限制,只收取最近30天的邮件,但是我遇到的并不是这个问题。我是先获取了收信箱所有邮件的数量,然后读取最近的cnt封邮件:

//读取索引从from到to的所有邮件
Message[] messages = folder.getMessages(from,n);

当程序在进行第一次读取时,就抛出了异常。

经过一番尝试,我又使用日期范围去进行搜索邮件

// 获取当前日期和30天前的日期
Calendar cal = Calendar.getInstance();
cal.add(Calendar.DAY_OF_MONTH, -30);
Date thirtyDaysAgo = cal.getTime();
// 创建一个搜索条件,限制邮件日期在30天内
SearchTerm searchTerm = new ReceivedDateTerm(ComparisonTerm.GT, thirtyDaysAgo);

// 使用搜索条件来搜索邮件
Message[] messages = folder.search(searchTerm);

发现这次读取邮件时,并没有报上面的错误,不明觉厉,不明白是什么原因导致的。

你可能感兴趣的:(java,java)