您的位置:首页 > 数据 >
QQ邮箱发邮件受限制怎么办?SMTP发送邮件限制的解决方案|天天即时
来源:CSDN 2023-01-28 09:21:41

由于QQ邮箱对于SMTP服务发送邮件做了限制,每分钟发送40封之后会被限制不能再发送,对于这样的限制又需要发送大量邮件的时候的解决方案如下

使用多个邮箱轮换使用进行发送


(相关资料图)

1、将使用的邮箱存储在一个统一的字符串变量中,将所有可使用的邮箱存储在一个字符串数组中(我的三个邮箱授权码相同,如果授权码不同,则建立一个授权码数组,和邮箱切换的解决方案同理)

全局变量(发邮件使用的邮箱)

可使用的邮箱数组

2、将建立连接的代码封装到一个函数,将连接对象变为成员变量,全局化,即每次调用同一个变量,而变量的对象可能不相同(会变化)

连接相关对象变为全局变量

private static Properties props;    private static Session mailSession;    private static MimeMessage message;    private static Transport transport;

建立连接的函数

private void init()    {        System.out.println("QQ邮件服务初始化开始:账号"+FPAMail);        Date start=new Date();        try {            // 创建Properties 类用于记录邮箱的一些属性            props = new Properties();            // 表示SMTP发送邮件,必须进行身份验证            props.put("mail.smtp.auth", "true");            //此处填写SMTP服务器            props.put("mail.smtp.host", "smtp.qq.com");            //端口号,QQ邮箱给出了两个端口,但是另一个我一直使用不了,所以就给出这一个587            props.put("mail.smtp.port", "587");            // 此处填写你的账号            props.put("mail.user",FPAMail );            // 此处的密码就是前面说的16位STMP口令            props.put("mail.password", FPAMailPwd);            // 构建授权信息,用于进行SMTP进行身份验证            Authenticator authenticator = new Authenticator() {                protected PasswordAuthentication getPasswordAuthentication() {                    // 用户名、密码                    String userName = props.getProperty("mail.user");                    String password = props.getProperty("mail.password");                    return new PasswordAuthentication(userName, password);                }            };            // 使用环境属性和授权信息,创建邮件会话            mailSession = Session.getInstance(props, authenticator);// 创建邮件消息            message = new MimeMessage(mailSession);            // 设置发件人            InternetAddress form = new InternetAddress(                    props.getProperty("mail.user"),NickName,"utf-8");            message.setFrom(form);        }catch (Exception e)        {            e.printStackTrace();        }        Date end=new Date();        System.out.println("QQ邮件发送会话初始化成功,耗时"+((end.getTime()-start.getTime()))+"毫秒");    }

(不懂这几个对象是干嘛的百度)

3、设置每发送20封邮件切换一次邮箱,封装成函数

函数如下:

private void switchMail(){    int i=0;    for (;i<FPAMAILARRAY.LENGTH;I++) (fpamail.equals(fpamailarray[i]))="" break;="" if="" (i+1="=FPAMailArray.length)" i="0;" else="" i++;="" fpamail="FPAMailArray[i];" init();}

4、每次发送邮件的时候做判断(i%20==0)

public void sendToAllMember(String title,String html_content)    {        System.out.println("发送邮件给所有会员");        int i=1;        for (String mail: MemberQQMailData.mails)        {            System.out.println("正在处理第"+(i++)+"个"+"剩余"+(MemberQQMailData.mails.length-i+1)+"个,正在发送给:"+mail);            sendQQMail(title,MailContentGenerator.QQMailNotice(title,html_content),mail);            if (i%20==0)                switchMail();        }    }

(MemberQQMailData.mails是一个字符串数组,存有所有会员的QQ邮箱)

效果图:每到第20封邮件就换一个邮箱进行发送,完美解决QQ邮箱发送限制问题

新版解决方案代码工具类

新版工具类代码

package cn.freeprogramming.util;import cn.hutool.core.date.StopWatch;import lombok.extern.slf4j.Slf4j;import org.springframework.scheduling.annotation.Async;import javax.mail.*;import javax.mail.internet.InternetAddress;import javax.mail.internet.MimeMessage;import java.util.ArrayList;import java.util.List;import java.util.Objects;import java.util.Properties;import java.util.concurrent.locks.ReentrantLock;/** * QQ邮件发送工具 * * @Author:humorchen * @Date 2022/1/3 20:50 */@Slf4jpublic class QQMailUtil {    /**     * 超时时间     */    private long TIMEOUT = 5000;    /**     * 重试次数     */    private int RETRY_LIMIT = 10;    /**     * 使用第多少个账号(QQ每个账号限制频率了)     */    private int accountIndex = 0;    /**     * 锁     */    private ReentrantLock lock = new ReentrantLock(true);    /**     * 账号列表     */    private ListaccountList = new ArrayList<>();    /**     * 配置列表     */    private ListpropertiesList = new ArrayList<>();    /**     * 授权器     */    private ListauthenticatorList = new ArrayList<>();    /**     * 会话列表     */    private ListsessionList = new ArrayList<>();    /**     * 消息对象列表     */    private ListmessageList = new ArrayList<>();    /**     * 发件人地址信息列表     */    private ListinternetAddressArrayList = new ArrayList<>();    /**     * 发送器列表     */    private ListtransportList = new ArrayList<>();    /**     * 切换发件使用的邮箱下标     */    private void changeUsingAccountIndex() {        if (accountIndex == accountList.size() - 1) {            accountIndex = 0;        } else {            accountIndex++;        }    }    /**     * 与QQ邮箱服务器建立连接     *     * @throws Exception     */    private void connect() throws Exception {        QQMailAccount qqMailAccount = accountList.get(accountIndex);        Properties properties = propertiesList.get(accountIndex);        Authenticator authenticator = authenticatorList.get(accountIndex);        Session session = Session.getInstance(properties, authenticator);        MimeMessage message = new MimeMessage(session);        InternetAddress senderInternetAddress = internetAddressArrayList.get(accountIndex);        // 设置发件人        InternetAddress fromInternetAddress = new InternetAddress(                qqMailAccount.getAccount(), qqMailAccount.getNickname(), "utf-8");        message.setFrom(fromInternetAddress);        sessionList.set(accountIndex, session);        messageList.set(accountIndex, message);        Transport transport = session.getTransport(senderInternetAddress);        transport.connect();        log.info("isConnected {}", transport.isConnected());        if (accountIndex < transportList.size()) {            transportList.set(accountIndex, transport);        } else {            transportList.add(transport);        }    }    /**     * 发送邮件方法     * 由线程池处理     *     * @param title        邮件标题     * @param html_content 邮件内容(支持html,图片等内容可能会被拦截,需要用户点击查看才能看到,或者让用户设置信任这个邮箱)     * @param receiver     收件人邮箱     */    @Async    public void sendQQMail(String title, String html_content, String receiver) {        StopWatch stopWatch = new StopWatch();        try {            lock.lock();            log.info("发送邮件给 {} ,标题:{} ,\n内容:{}", receiver, title, html_content);            stopWatch.start();            QQMailAccount qqMailAccount = accountList.get(accountIndex);            Transport transport = transportList.get(accountIndex);            MimeMessage message = messageList.get(accountIndex);            if (transport == null || !transport.isConnected()) {                connect();            }            stopWatch.stop();            log.info("连接花费 {}ms", stopWatch.getTotalTimeMillis());            stopWatch.start();            // 设置收件人的邮箱            message.setRecipient(Message.RecipientType.TO, new InternetAddress(receiver));            // 设置邮件标题            message.setSubject(title, "utf-8");            // 设置邮件的内容体            message.setContent(html_content, "text/html;charset=UTF-8");            try {                //保存修改                message.saveChanges();                //发送邮件                transport.sendMessage(message, new InternetAddress[]{new InternetAddress(receiver)});                stopWatch.stop();                log.info("使用邮箱:{} 发送成功,花费时间:{}ms", qqMailAccount.getAccount(), stopWatch.getTotalTimeMillis());            } catch (Exception e) {                //由于被腾讯方面因超时被关闭连接属于正常情况                log.info("邮件发送失败,正在尝试和QQ邮件服务器重新建立链接");                stopWatch.stop();                stopWatch.start();                boolean success = false;                for (int i = 1; i <= RETRY_LIMIT; i++) {                    try {                        connect();                        log.info("使用邮箱:{} 成功建立链接", qqMailAccount.getAccount());                        transport = transportList.get(accountIndex);                        message = messageList.get(accountIndex);                        success = true;                        break;                    } catch (Exception ee) {                        changeUsingAccountIndex();                        qqMailAccount = accountList.get(accountIndex);                        log.info("链接建立失败,切换到邮箱:{} ,进行第 {} 次重试..." + qqMailAccount.getAccount(), i);                    }                }                if (success) {                    // 设置收件人的邮箱                    message.setRecipient(Message.RecipientType.TO, new InternetAddress(receiver));                    // 设置邮件标题                    message.setSubject(title, "utf-8");                    // 设置邮件的内容体                    message.setContent(html_content, "text/html;charset=UTF-8");                    message.saveChanges();                    transport.sendMessage(message, new InternetAddress[]{new InternetAddress(receiver)});                    stopWatch.stop();                    log.info("重建连接后使用邮箱:{} 发送成功,耗费时间:{}ms", qqMailAccount.getAccount(), stopWatch.getTotalTimeMillis());                } else {                    log.error("链接多次尝试后无法建立,邮件发送失败!");                    return;                }            }        } catch (Exception e) {            log.error("sendQQMail", e);        } finally {            lock.unlock();            if (stopWatch.isRunning()) {                stopWatch.stop();            }        }    }    /**     * 添加账号     */    public void addAccount(String account, String authorizationCode, String nickname) {        int oldAccountIndex = accountIndex;        boolean addFinished = false;        try {            lock.lock();            oldAccountIndex = accountIndex;            accountIndex = accountList.size();            QQMailAccount qqMailAccount = new QQMailAccount(account, authorizationCode, nickname);            Properties properties = createProperties(qqMailAccount);            Authenticator authenticator = createAuthenticator(qqMailAccount);            // 使用环境属性和授权信息,创建邮件会话            Session session = Session.getInstance(properties, authenticator);            MimeMessage message = new MimeMessage(session);            // 设置发件人            InternetAddress internetAddress = new InternetAddress(                    account, nickname, "utf-8");            message.setFrom(internetAddress);            Transport transport = session.getTransport(new InternetAddress(qqMailAccount.getAccount()));            transport.connect();            accountList.add(qqMailAccount);            propertiesList.add(properties);            authenticatorList.add(authenticator);            sessionList.add(session);            transportList.add(transport);            messageList.add(message);            internetAddressArrayList.add(internetAddress);            addFinished = true;        } catch (Exception e) {            //移除已经加入的            if (addFinished) {                accountList.remove(accountIndex);                propertiesList.remove(accountIndex);                authenticatorList.remove(accountIndex);                sessionList.remove(accountIndex);                transportList.remove(accountIndex);                messageList.remove(accountIndex);                internetAddressArrayList.remove(accountIndex);            }            log.error("addAccount", e);        } finally {            accountIndex = oldAccountIndex;            lock.unlock();        }    }    /**     * 创建配置文件     *     * @param qqMailAccount     * @return     */    private Properties createProperties(QQMailAccount qqMailAccount) {        // 创建Properties 类用于记录邮箱的一些属性        Properties properties = new Properties();        // 表示SMTP发送邮件,必须进行身份验证        properties.put("mail.smtp.auth", "true");        //此处填写SMTP服务器        properties.put("mail.smtp.host", "smtp.qq.com");        //端口号,QQ邮箱给出了两个端口,但是另一个我一直使用不了,所以就给出这一个587        properties.put("mail.smtp.port", "587");        // 此处填写你的账号        properties.put("mail.user", qqMailAccount.getAccount());        // 此处的密码就是前面说的16位STMP口令        properties.put("mail.password", qqMailAccount.getAuthorizationCode());        //设置超时时间        properties.put("mail.smtp.timeout", "" + TIMEOUT);        return properties;    }    /**     * 创建授权信息对象     *     * @param qqMailAccount     * @return     */    private Authenticator createAuthenticator(QQMailAccount qqMailAccount) {        // 构建授权信息,用于进行SMTP进行身份验证        Authenticator authenticator = new Authenticator() {            @Override            protected PasswordAuthentication getPasswordAuthentication() {                // 用户名、密码                String userName = qqMailAccount.getAccount();                String password = qqMailAccount.getAuthorizationCode();                return new PasswordAuthentication(userName, password);            }        };        return authenticator;    }    private static class QQMailAccount {        /**         * 账号         */        private String account;        /**         * 授权码         */        private String authorizationCode;        /**         * 发送者昵称         */        private String nickname;        public QQMailAccount(String account, String authorizationCode, String nickname) {            this.account = account;            this.authorizationCode = authorizationCode;            this.nickname = nickname;        }        public String getAccount() {            return account;        }        public void setAccount(String account) {            this.account = account;        }        public String getAuthorizationCode() {            return authorizationCode;        }        public void setAuthorizationCode(String authorizationCode) {            this.authorizationCode = authorizationCode;        }        public String getNickname() {            return nickname;        }        public void setNickname(String nickname) {            this.nickname = nickname;        }        @Override        public boolean equals(Object o) {            if (this == o) return true;            if (o == null || getClass() != o.getClass()) return false;            QQMailAccount that = (QQMailAccount) o;            return Objects.equals(account, that.account) && Objects.equals(authorizationCode, that.authorizationCode) && Objects.equals(nickname, that.nickname);        }        @Override        public int hashCode() {            return Objects.hash(account, authorizationCode, nickname);        }    }}

配置工具类对象到容器

package cn.freeprogramming.config;import cn.freeprogramming.util.QQMailUtil;import org.springframework.context.annotation.Bean;import org.springframework.context.annotation.Configuration;/** * QQ邮件配置 * * @Author:humorchen * @Date 2022/1/3 21:54 */@Configurationpublic class QQMailConfig {    //授权码,在QQ邮箱里设置    private String authorizationCode = "hkkm123kasbjbf";    private String nickname = "自由编程协会";    @Bean    public QQMailUtil qqMailUtil() {        QQMailUtil qqMailUtil = new QQMailUtil();        qqMailUtil.addAccount("freeprogramming@qq.com", authorizationCode, nickname);        qqMailUtil.addAccount("freeprogramming@foxmail.com", authorizationCode, nickname);        qqMailUtil.addAccount("357341307@qq.com", authorizationCode, nickname);        return qqMailUtil;    }}

关键词: 发送邮件
相关文章
当前滚动:四川铁路电煤专列同比增长9.8%

当前滚动:四川铁路电煤专列同比增长9.8%

  今年春运以来,中国铁路成都局集团有限公司已抢卸电煤3万余车、190万余吨,其中,四川地区已抢卸电煤13万余车、83万余吨,卸车数同比增长9更多

2023-01-28 09:17:28
内蒙古:煤企生产忙 供应不断档

内蒙古:煤企生产忙 供应不断档

  春节假期,位于内蒙古乌海市的国家能源集团乌海能源公司加强煤炭生产组织,确保煤炭供应不断档。乌海能源公司提前制定计划,适时调整煤炭更多

2023-01-28 09:15:32
陕煤入渝发运量再创新高 2022年达1798.3万吨 环球速看料

陕煤入渝发运量再创新高 2022年达1798.3万吨 环

  据陕煤运销集团统计数据显示,2022年陕煤入渝发运量17983万吨,同比增长132%,入渝年度发运量创下历史新纪录,有效保障了重庆地区电力和重更多

2023-01-20 11:10:02
全球快看:为完成2023年煤炭供应目标 晋城市出台了7项措施

全球快看:为完成2023年煤炭供应目标 晋城市出台

  晋城市能源局消息,该市日前发布了煤炭增产保供和产能新增工作方案并提出,通过核增产能、扩产、新投产等方式,加快释放先进产能,充分发更多

2023-01-20 11:09:59
当前关注:2022年内蒙古煤电气产量对全国增长贡献均居首位

当前关注:2022年内蒙古煤电气产量对全国增长贡献

  2022年,内蒙古全区积极落实煤电增产保供工作,规模以上工业煤电气等主要能源产品产量均位居全国前列,对全国增长贡献率均位居首位,有力更多

2023-01-20 11:11:26
全球微速讯:山东:细化分解任务 坚决完成煤炭保供任务

全球微速讯:山东:细化分解任务 坚决完成煤炭保

  山东省政府工作报告提出,要抓好能源保供。菏泽代表团三名来自煤炭企业的省人大代表,围绕报告精神,就如何保障煤炭供应,加强能源保供建更多

2023-01-20 10:54:12
CCTD:短期煤市基本面仍难寻亮点

CCTD:短期煤市基本面仍难寻亮点

  据CCTD了解,节前最后一周,煤炭市场交易逐渐停滞,周初在封航港口库存迅速累积情况下,贸易商报价有小幅下跌。随后封航结束,港口调出恢更多

2023-01-20 11:02:24
每日观察!12月份内蒙古煤炭价格环比下降8.3%

每日观察!12月份内蒙古煤炭价格环比下降8.3%

  2022年12月份受疫情防控、原油价格变化,农业生产进程和建筑工程进展等因素影响,煤炭价格环比下降。据内蒙古自治区商务厅生产资料市场监更多

2023-01-19 10:54:37
促开采、增储备、抢维修、保运输,各地多措并举——力保群众温暖过冬过年 焦点速讯

促开采、增储备、抢维修、保运输,各地多措并举—

  中央经济工作会议要求,要做好岁末年初各项工作,强化市场保供稳价,加强能源调节,确保群众温暖安全过冬。冬季供暖事关千家万户,是重要更多

2023-01-19 10:08:31
生态环境部:推动保供煤矿全部按时保质完成环评办理

生态环境部:推动保供煤矿全部按时保质完成环评办

  生态环境部环境影响评价与排放管理司司长刘志全17日在新闻发布会上表示,2023年将落实环评审批三本台账和绿色通道机制,推进十四五重大工更多

2023-01-19 08:59:13