【Java】JavaMail使用网易企业邮箱发邮件

邮件发送器

/**
 * 邮件发送器
 *
 * @author Zebe
 */
public class MailSender implements Runnable {

    /**
     * 收件人
     */
    private String to;

    /**
     * 收件人名称
     */
    private String toName;

    /**
     * 主题
     */
    private String subject;

    /**
     * 内容
     */
    private String content;

    /**
     * 附件列表
     */
    private List<String> attachFileList;

    /**
     * 构造器
     * @param to 收件人
     * @param subject 主题
     * @param content 内容
     */
    public MailSender(String to,String toName, String subject, String content) {
        this.to = to;
        this.toName = toName;
        this.subject = subject;
        this.content = content;
    }

    /**
     * 构造器
     * @param to 收件人
     * @param subject 主题
     * @param content 内容
     * @param attachFileList 附件列表
     */
    public MailSender(String to, String toName,String subject, String content, List<String> attachFileList) {
        this(to, toName, subject, content);
        this.attachFileList = attachFileList;
    }

    @Override
    public void run() {
        new SendEmailUtil(to,toName, subject, content, attachFileList).send();
    }

}

邮件发送线程池

/**
 * 邮件发送线程池
 *
 * @author Zebe
 */
public class MailSenderPool {

    /**
     * 邮件发送器线程数量
     */
    private static int SENDER_TOTAL = 10;

    /**
     * 线程工厂(生产环境中建议使用带命名参数的线程工厂)
     */
    private static ThreadFactory threadFactory = Executors.defaultThreadFactory();

    /**
     * 线程池执行器(采用了Spring提供的CustomizableThreadFactory,如果不需要请使用默认线程工厂)
     */
    private static ExecutorService executor = new ThreadPoolExecutor(SENDER_TOTAL, 200,
            0L, TimeUnit.MILLISECONDS, new LinkedBlockingQueue<>(1024), threadFactory,
            new ThreadPoolExecutor.AbortPolicy());

    /**
     * 内部静态实例
     */
    private static class Inner {
        private static MailSenderPool instance = new MailSenderPool();
    }

    /**
     * 获取实例
     *
     * @return 返回邮件发送线程池实例
     */
    public static MailSenderPool getInstance() {
        return Inner.instance;
    }

    /**
     * 通过线程发送
     *
     * @param sender 邮件发送器
     * @return 返回自身
     */
    public MailSenderPool sendByThread(MailSender sender) {
        executor.execute(sender);
        return getInstance();
    }

    /**
     * 关闭线程池
     */
    public void shutDown() {
        executor.shutdown();
    }

}

邮件发送工具类

/**
 * 邮件发送工具类。
 * 以下邮件中的配置参数,请在实际环境中,根据需要采取合适的配置方式。
 * 发送邮件依赖 com.sun.mail(1.6.1) 包、javax.mail(1.5.0-b01) 包。
 * 如果使用 Idea 运行,请将这两个包(可以直接到Maven目录下面去找)添加到项目的 Libraries 里面(快捷键:Ctrl + Alt + Shift + S)
 *
 * @author Zebe
 */
public class SendEmailUtil {

    /**
     * 发件人别名(可以为空)
     */
    private final static String fromAliasName = "****";

    /**
     * 登录用户名
     */
    private String ACCOUNT;

    /**
     * 登录密码
     */
    private String PASSWORD;

    /**
     * 邮件服务器地址
     */
    //QQ企业邮箱:smtp.exmail.qq.com
    //网易企业邮箱:smtphz.qiye.163.com
    private String HOST;

    /**
     * 发信端口
     */
    //QQ企业邮箱:465
    //网易企业邮箱:994
    private String PORT;

    /**
     * 发信协议
     */
    private final static String PROTOCOL = "ssl";

    /**
     * 收件人
     */
    private String to;

    /**
     * 收件人名称
     */
    private String toName;

    /**
     * 主题
     */
    private String subject;

    /**
     * 内容
     */
    private String content;

    /**
     * 附件列表(可以为空)
     */
    private List<String> attachFileList;

    /**
     * 构造器
     *
     * @param attachFileList 附件列表
     */
    public SendEmailUtil(MailTemplate mailTemplate, List<String> attachFileList) {
        this.to = mailTemplate.getTo();
        this.toName = mailTemplate.getToName();
        this.subject = mailTemplate.getSubject();
        this.content =  mailTemplate.getContent();
        this.attachFileList = attachFileList;
        this.ACCOUNT = mailTemplate.getAccount();
        this.PASSWORD = mailTemplate.getPassword();
        switch (mailTemplate.getSendType()) {
            case "qq":
                this.HOST = "smtp.exmail.qq.com";
                this.PORT = "465";
                break;
            case "163":
                this.HOST = "smtp.ym.163.com";
                this.PORT = "994";
                break;
        }
    }

    /**
     * 认证信息
     */
    static class MyAuthenticator extends Authenticator {

        /**
         * 用户名
         */
        String username = null;

        /**
         * 密码
         */
        String password = null;

        /**
         * 构造器
         *
         * @param username 用户名
         * @param password 密码
         */
        public MyAuthenticator(String username, String password) {
            this.username = username;
            this.password = password;
        }

        @Override
        protected PasswordAuthentication getPasswordAuthentication() {
            return new PasswordAuthentication(username, password);
        }
    }

    /**
     * 发送邮件
     */
    public boolean send() {
        // 设置邮件属性
        Properties prop = new Properties();
        prop.setProperty("mail.transport.protocol", PROTOCOL);
        prop.setProperty("mail.smtp.host", HOST);
        prop.setProperty("mail.smtp.port", PORT);
        prop.setProperty("mail.smtp.auth", "true");
        MailSSLSocketFactory sslSocketFactory = null;
        try {
            sslSocketFactory = new MailSSLSocketFactory();
            sslSocketFactory.setTrustAllHosts(true);
        } catch (GeneralSecurityException e1) {
            e1.printStackTrace();
        }
        if (sslSocketFactory == null) {
            System.err.println("开启 MailSSLSocketFactory 失败");
        } else {
            prop.put("mail.smtp.ssl.enable", "true");
            prop.put("mail.smtp.ssl.socketFactory", sslSocketFactory);
            // 创建邮件会话(注意,如果要在一个进程中切换多个邮箱账号发信,应该用 Session.getInstance)
            Session session = Session.getDefaultInstance(prop, new MyAuthenticator(ACCOUNT, PASSWORD));
            // 开启调试模式(生产环境中请不要开启此项)
            session.setDebug(true);
            try {
                MimeMessage mimeMessage = new MimeMessage(session);
                // 设置发件人别名(如果未设置别名就默认为发件人邮箱)
                mimeMessage.setFrom(new InternetAddress(ACCOUNT, fromAliasName));
                // 设置主题和收件人、发信时间等信息
                mimeMessage.addRecipient(Message.RecipientType.TO, new InternetAddress(to, toName));
                mimeMessage.setSubject(subject);
                mimeMessage.setSentDate(new Date());

                //图片
                MimeBodyPart img = new MimeBodyPart();
                DataHandler dh = new DataHandler(new FileDataSource("src/main/resources/2.jpg"));//图片路径
                img.setDataHandler(dh);
                img.setContentID("img");
                //正文
                MimeBodyPart text = new MimeBodyPart();
                text.setContent("这里正文内容  for img<img src='cid:img'><br/>", "text/html;charset=utf-8"); //注意编码问题

                //描述数据关系
                MimeMultipart mm = new MimeMultipart();
                mm.addBodyPart(text);
                mm.addBodyPart(img);
                mm.setSubType("related");

                //图片-文本--复合--转普通节点
                MimeBodyPart tex_image_tPart=new MimeBodyPart();
                tex_image_tPart.setContent(mm);

                // 如果有附件信息,则添加附件
                if (!attachFileList.isEmpty()) {
                    Multipart multipart = new MimeMultipart();
                    MimeBodyPart body = new MimeBodyPart();
                    body.setContent(content, "text/html; charset=UTF-8");
                    multipart.addBodyPart(body);
                    // 添加所有附件(添加时判断文件是否存在)
                    for (String filePath : attachFileList) {
                        if (Files.exists(Paths.get(filePath))) {
                            MimeBodyPart tempBodyPart = new MimeBodyPart();
                            tempBodyPart.attachFile(filePath);
                            multipart.addBodyPart(tempBodyPart);
                        }
                    }
                    mimeMessage.setContent(multipart);
                } else {
//                    Multipart multipart = new MimeMultipart();
//                    MimeBodyPart body = new MimeBodyPart();
//                    body.setContent(mm, "text/html; charset=UTF-8");
//                    multipart.addBodyPart(body);
                    MimeMultipart mimeMultipart1=new MimeMultipart();
                    mimeMultipart1.addBodyPart(tex_image_tPart);
                    mimeMultipart1.setSubType("mixd");//混合关系
                    mimeMessage.setContent(mimeMultipart1, "text/html; charset=UTF-8");
                    //mimeMessage.setText(content);
                }
                // 开始发信
                mimeMessage.saveChanges();
                Transport.send(mimeMessage);
                return true;
            } catch (MessagingException | IOException e) {
                e.printStackTrace();
                return false;
            }
        }
        return false;
    }
}

示例

    public static void main(String[] args) {
        try {
            int num;
            // 通过线程池发送邮件
            MailSenderPool pool = MailSenderPool.getInstance();
            for (num=1;num<=73;num++){
                // 设置发信参数
                final String toName = "我是" + num + "号";
                final String to = "test" + num + "@***.com";
                String subject = num + " 第一次发送测试邮件标题";
                final String content = "<p style='color:red'>这是邮件内容正文。</p>";
                // 设置附件路径(注意:res 是项目根目录下的一个文件夹)
                // final List<String> attachFileList = Arrays.asList("res/1.png", "res/1.pdf");
                pool.sendByThread(new MailSender(to,toName, subject, content, new ArrayList<>()));
                subject = num + " 第二次发送测试邮件标题";
                pool.sendByThread(new MailSender(to,toName, subject, content, new ArrayList<>()));
            }
            pool.shutDown();
        }catch (Exception e){
            System.out.println("错误: " + e);
        }
    }

 


posted @ 2019-11-28 14:50    阅读(1158)  评论(0编辑  收藏  举报