JavaMail发送邮件实例

记录下JavaMail简单邮件发送:

import javax.activation.DataHandler;
import javax.activation.FileDataSource;
import javax.mail.MessagingException;
import javax.mail.Session;
import javax.mail.Transport;
import javax.mail.event.TransportEvent;
import javax.mail.event.TransportListener;
import javax.mail.internet.*;
import java.io.UnsupportedEncodingException;
import java.util.Date;
import java.util.Properties;

/**
 * 邮件发送工具类
 *
 * @author tinkerz
 * @version 1.0
 * @date 2021-06-17 10:20:13
 */
public class MailUtils {

    /**
     * 发送需要认证
     */
    public static final String SMTP_AUTH = "true";
    /**
     * 数据传递协议-smtp
     */
    public static final String PROTOCOL = "smtp";
    /**
     * 超时时间 5s
     */
    public static final String TIMEOUT = "5000";
    /**
     * 马甲 outlook,防止收件到垃圾邮件,不是很好使
     */
    public static final String X_MAILER = "Microsoft Outlook Express 6.00.2900.2869";
    /**
     * 编码格式
     */
    public static final String CHARSET = "UTF-8";

    /**
     * 发送邮件
     *
     * @param: mailVo 发送邮件需要的参数类
     * @return:
     * @author:         tinkerz
     * @version:        1.0
     * @createDate:     2021-06-17 15:49
     */
    public static String sendMail(MailVo mailVo) throws MessagingException, UnsupportedEncodingException {
        String status = StringUtils.EMPTY;
        // 获取邮件服务器配置
        Properties props = new Properties();
        //设置用户的认证方式
        props.setProperty("mail.smtp.auth", SMTP_AUTH);
        //设置传输协议
        props.setProperty("mail.transport.protocol", PROTOCOL);
        //设置发件人的SMTP服务器地址
        props.setProperty("mail.smtp.host", mailVo.getHost());
        // 连接协议
        props.setProperty("mail.smtp.timeout",TIMEOUT);
        // Session对象
        Session session = Session.getInstance(props);
        // 是否打开debug日志输出
        // session.setDebug(true);
        // 创建邮件的实例对象
        MimeMessage message = new MimeMessage(session);
        /**
         * 设置收件人地址(可以增加多个收件人、抄送、密送),即下面这一行代码书写多行
         * MimeMessage.RecipientType.TO:发送
         * MimeMessage.RecipientType.CC:抄送
         * MimeMessage.RecipientType.BCC:密送
         */
        message.addHeader("X-Mailer",X_MAILER);
        message.setFrom(new InternetAddress(mailVo.getFrom(),mailVo.getSenderNameAlias()));
        // 收件人
        message.setRecipient(MimeMessage.RecipientType.TO,new InternetAddress(mailVo.getEmailAddress()));
        //多个收件人情况
        // InternetAddress[] internetAddresses = new InternetAddress[5];
        // message.setRecipients(MimeMessage.RecipientType.TO,internetAddresses);
        // 邮件标题
        message.setSubject(mailVo.getEmailTitle(),CHARSET);
        // 设置邮件正文,简单的纯文本本间
        //message.setContent("呵呵哒!", "text/html;charset=UTF-8");
        // 创建图片正文
        MimeBodyPart image = new MimeBodyPart();
        DataHandler dataHandler = new DataHandler(new FileDataSource(mailVo.getImageUrl()));
        image.setDataHandler(dataHandler);
        // 为"节点"设置一个唯一编号(在文本"节点"将引用该ID)
        image.setContentID("mailDetailPic");
        // 创建文本正文
        MimeBodyPart text = new MimeBodyPart();
        text.setContent("<div><span><a href='"+mailVo.getDashboardUrl()+"'>点击查看详情</a></span><br/><img src='cid:mailDetailPic'/></div>", "text/html;charset=UTF-8");

        // (文本+图片)设置 文本 和 图片"节点"的关系(将 文本 和 图片"节点"合成一个混合"节点")
        MimeMultipart mm_text_image = new MimeMultipart();
        mm_text_image.addBodyPart(text);
        mm_text_image.addBodyPart(image);
        // 关联关系
        mm_text_image.setSubType("related");

        /** 将 文本+图片 的混合"节点"封装成一个普通"节点"
         *  最终添加到邮件的 Content 是由多个 BodyPart 组成的 Multipart, 所以需要的是 BodyPart,
         *  上面的 mailDetailPic 并非 BodyPart, 所有要把 mm_text_image 封装成一个 BodyPart
         *
         */
        MimeBodyPart text_image = new MimeBodyPart();
        text_image.setContent(mm_text_image);
        /*
            // 创建附件"节点"
            MimeBodyPart attachment = new MimeBodyPart();
            // 读取本地文件
            DataHandler dh2 = new DataHandler(new FileDataSource("C:\\Users\\xxx\\Downloads\\xxx.jpg"));
            // 将附件数据添加到"节点"
            attachment.setDataHandler(dh2);
            // 设置附件的文件名(需要编码)
            attachment.setFileName(MimeUtility.encodeText(dh2.getName()));
        */
        // 设置(文本+图片)和 附件 的关系(合成一个大的混合"节点" / Multipart )
        MimeMultipart mm = new MimeMultipart();
        mm.addBodyPart(text_image);
        // 如果有多个附件,可以创建多个多次添加
//        mm.addBodyPart(attachment);
        // 混合关系
        mm.setSubType("mixed");
        //设置整个邮件的关系(将最终的混合"节点"作为邮件的内容添加到邮件对象)
        message.setContent(mm);
        //设置邮件的发送时间,默认立即发送
        message.setSentDate(new Date());
        //4、根据session对象获取邮件传输对象Transport
        Transport transport = session.getTransport();
        final DeliveredStateFuture future = new DeliveredStateFuture();
        transport.addTransportListener(new TransportListener() {
            @Override
            public void messageDelivered(TransportEvent transportEvent) {
                future.setState(DeliveredState.MESSAGE_DELIVERED);
            }

            @Override
            public void messageNotDelivered(TransportEvent transportEvent) {
                future.setState(DeliveredState.MESSAGE_NOT_DELIVERED);
            }

            @Override
            public void messagePartiallyDelivered(TransportEvent transportEvent) {
                future.setState(DeliveredState.MESSAGE_PARTIALLY_DELIVERED);
            }
        });
        //设置发件人的账户名和密码
        transport.connect(mailVo.getSenderName(), mailVo.getPassword());
        //发送邮件,并发送到所有收件人地址,message.getAllRecipients() 获取到的是在创建邮件对象时添加的所有收件人, 抄送人, 密送人
        transport.sendMessage(message,message.getAllRecipients());
        transport.close();
        status = future.getState().getInfo();
        return status;
    }

    private enum DeliveredState {
        INITIAL("初始化"), MESSAGE_DELIVERED("已发送"), MESSAGE_NOT_DELIVERED("未发送"), MESSAGE_PARTIALLY_DELIVERED("不完全发送");

        private String msg;

        DeliveredState(String msg) {
            this.msg = msg;
        }

        public String getInfo(){
            return msg;
        }
    }
    private static class DeliveredStateFuture {
        private DeliveredState state = DeliveredState.INITIAL;
        synchronized void waitForReady() throws InterruptedException {
            if (state == DeliveredState.INITIAL) {
                wait();
            }
        }
        synchronized DeliveredState getState() {
            return state;
        }
        synchronized void setState(DeliveredState newState) {
            state = newState;
            notifyAll();
        }
    }

    public static void main(String[] args) throws UnsupportedEncodingException, MessagingException {
        MailVo mailVo = new MailVo();
        //收件人邮箱
        mailVo.setEmailAddress("");
        // 图片地址,绝对路径
        mailVo.setImageUrl("C:\\Users\\xxx\\Downloads\\庖丁解牛.png");
        // 邮件标题
        mailVo.setEmailTitle("庖丁解牛-测试发送");
        // 可编辑url
        mailVo.setDashboardUrl("www.baidu.com");
        // 发件人登录名
        mailVo.setSenderName("xxxx");
        // 发件人密码
        mailVo.setPassword("xxxxx");
        // 发件人显示名称
        mailVo.setSenderNameAlias("xxxx");
        // smtp发件服务器地址
        mailVo.setHost("smtp.163.com");
        // 发件人邮箱
        mailVo.setFrom("xxxx");
        String mail = sendMail(mailVo);
        System.out.println(mail);
    }
}

 

posted @ 2021-06-28 14:45  再见泰戈尔  阅读(272)  评论(0)    收藏  举报