# JavaMail发送邮件_jamebestwick的博客-CSDN博客

By [jambestwick](https://paragraph.com/@vatalikbuterin) · 2022-02-08

---

通过指令自动化的发送邮件
------------

提示：文章写完后，目录可以自动生成，如何生成可参考右边的帮助文档

### 文章目录

*   通过指令自动化的发送邮件
    
*   前言
    
*   一、Mail（邮件）
    
*   二、使用步骤
    
*   1.引入库
    
    *   2.开启邮件服务商：POP3/SMTP服务
        
    *   发送QQ邮箱
        
        *   发送网易邮箱
            
*   总结
    

* * *

前言
--

JAVA作为BackEnd实现邮件的定时发送，批量发送对很多业务场景有这重要的意义。例如:给用户发送发票、订阅、广告、数据的报表推送、验证账号、验证码、定时回复等等业务场景均需要该功能。因此，简单总结了下自动化发送的注意点，及实现逻辑，望大家指正。原先的文章进行更新  
[javaMail发送邮件](https://blog.csdn.net/baidu_30084597/article/details/104917191)

* * *

正文内容

一、Mail（邮件）
----------

电子邮件是—种用电子手段提供信息交换的通信方式，是互联网应用最广的服务。通过网络的电子邮件系统，用户可以以非常低廉的价格（不管发送到哪里，都只需负担网费）、非常快速的方式（几秒钟之内可以发送到世界上任何指定的目的地），与世界上任何一个角落的网络用户联系。  
电子邮件可以是文字、图像、声音等多种形式。同时，用户可以得到大量免费的新闻、专题邮件，并轻松实现轻松的信息搜索。电子邮件的存在极大地方便了人与人之间的沟通与交流，促进了社会的发展。  
邮件是基于[SMTP](https://baike.baidu.com/item/SMTP)协议的一种传输方式。  
SMTP协议的工作过程可分为如下3个过程：

1.  建立连接：在这一阶段，SMTP客户请求与服务器的25端口建立一个TCP连接。一旦连接建立，SMTP服务器和客户就开始相互通告自己的域名，同时确认对方的域名。
    
2.  邮件传送：利用命令，SMTP客户将邮件的源地址、目的地址和邮件的具体内容传递给SMTP服务器，SMTP服务器进行相应的响应并接收邮件。
    
3.  连接释放：SMTP客户发出退出命令，服务器在处理命令后进行响应，随后关闭TCP连接。
    

> 邮件可以包括主题，标题、内容、附件等，附件包括音视频等各种文件类型。

![在这里插入图片描述](https://storage.googleapis.com/papyrus_images/db8b04e94587133c6b91ac7168b963666d6e5f5b70542cf252adbde34b0ebb6b.png)

在这里插入图片描述

二、使用步骤
------

1.引入库
-----

build.gradle（示例）：

        // https://mvnrepository.com/artifact/com.sun.mail/javax.mail
        compile group: 'com.sun.mail', name: 'javax.mail', version: '1.6.2'
    

Maven（示例）：

    <!-- https://mvnrepository.com/artifact/com.sun.mail/javax.mail -->
    <dependency>
        <groupId>com.sun.mail</groupId>
        <artifactId>javax.mail</artifactId>
        <version>1.6.2</version>
    </dependency>
    

2.开启邮件服务商：POP3/SMTP服务
---------------------

（以QQ邮箱为示例）：

1.  发送QQ邮箱
    

进入QQ邮箱，选择设置–>账户，找到 开启服务：POP3/SMTP服务，QQ会要求你发送XX短信到指定号码，发送成功后，QQ会返回一个授权码，用于第三方登录使用，**授权码一定要记住，后面程序发送邮件要用**，再次登录，他就不显示了。  
  

    package com.xxx.xxx.utils;
    
    import com.sun.mail.util.MailSSLSocketFactory;
    import org.apache.commons.lang.StringUtils;
    
    import javax.activation.DataHandler;
    import javax.activation.DataSource;
    import javax.activation.FileDataSource;
    import javax.mail.*;
    import javax.mail.internet.*;
    import java.io.UnsupportedEncodingException;
    import java.security.GeneralSecurityException;
    import java.util.Properties;
    
    /**
     * * Created by jambestwick1988@gmail.com
     * * github: jambestwick
     * * on 2020/3/11
     * 发送邮件工具
     * *
     */
    public class SendMailAcceUtils {
    
        /**
         * 发送带附件的邮件
         *
         * @param receive  收件人
         * @param subject  邮件主题
         * @param msg      邮件内容
         * @param filename 附件地址，本地文件
         * @return boolean
         */
        public static boolean sendQQMail(String receive, String subject, String msg, String filename) {
            if (StringUtils.isEmpty(receive)) {
                return false;
            }
            // 发件人电子邮箱
            final String from = "258702177@qq.com";
            // 发件人电子邮箱授权码
            final String pass = "xxxxxxxxxuuxxxxx";
    
            // 指定发送邮件的主机为 smtp.qq.com
            String host = "smtp.qq.com"; // 邮件服务器
    
            // 获取系统属性
            Properties properties = System.getProperties();
    
            // 设置邮件服务器
            properties.setProperty("mail.smtp.host", host);
            properties.put("mail.transport.protocol", "smtp");// 连接协议
            properties.put("mail.smtp.host", host);// 主机名
            properties.put("mail.smtp.port", 465);// 端口号
            properties.put("mail.smtp.auth", "true");
            properties.put("mail.smtp.ssl.enable", "true");// 设置是否使用ssl安全连接 ---一般都使用
            properties.put("mail.debug", "true");// 设置是否显示debug信息 true 会在控制台显示相关信息
            try {
                // 得到回话对象
                Session session = Session.getInstance(properties);
                // 获取邮件对象
                Message message = new MimeMessage(session);
                // 设置发件人邮箱地址
                message.setFrom(new InternetAddress(from));
                // 设置收件人邮箱地址
                //message.setRecipients(Message.RecipientType.TO, new InternetAddress[]{new InternetAddress(receive), new InternetAddress(receive), new InternetAddress(receive)});
                message.setRecipient(Message.RecipientType.TO, new InternetAddress(receive));//一个收件人
                // 设置邮件标题
                message.setSubject(subject);
                // 创建消息部分
                BodyPart messageBodyPart = new MimeBodyPart();
                // 消息
                messageBodyPart.setText(msg);
    
                // 创建多重消息
                Multipart multipart = new MimeMultipart();
    
                // 设置文本消息部分
                multipart.addBodyPart(messageBodyPart);
    
                // 附件部分
                messageBodyPart = new MimeBodyPart();
                // 设置要发送附件的文件路径
                DataSource source = new FileDataSource(filename);
                messageBodyPart.setDataHandler(new DataHandler(source));
    
                // messageBodyPart.setFileName(filename);
                // 处理附件名称中文（附带文件路径）乱码问题
                messageBodyPart.setFileName(MimeUtility.encodeText(filename));
                multipart.addBodyPart(messageBodyPart);
    
                // 发送完整消息
                message.setContent(multipart);
    
                // 得到邮差对象
                Transport transport = session.getTransport();
                // 连接自己的邮箱账户
                transport.connect(from, pass);// 密码为QQ邮箱开通的stmp服务后得到的客户端授权码
                // 发送邮件
                transport.sendMessage(message, message.getAllRecipients());
                transport.close();
                return true;
            } catch (MessagingException | UnsupportedEncodingException e) {
                e.printStackTrace();
            }
            return false;
        }
    
        /***
         * 不带有附件的方法
         * 可以将发送者封装提取出来，作为入参
         * **/
        public static boolean sendQQMailWithOutFile(String receive, String subject, String msg){
            if (StringUtils.isEmpty(receive)) {
                return false;
            }
            // 发件人电子邮箱
            final String from = "258702177@qq.com";
            // 发件人电子邮箱授权码
            final String pass = "xxxxxxxxxxxxxxxx";
    
            // 指定发送邮件的主机为 smtp.qq.com
            String host = "smtp.qq.com"; // 邮件服务器
    
            // 获取系统属性
            Properties properties = System.getProperties();
    
            // 设置邮件服务器
            properties.setProperty("mail.smtp.host", host);
            properties.put("mail.transport.protocol", "smtp");// 连接协议
            properties.put("mail.smtp.host", host);// 主机名
            properties.put("mail.smtp.port", 465);// 端口号
            properties.put("mail.smtp.auth", "true");
            properties.put("mail.smtp.ssl.enable", "true");// 设置是否使用ssl安全连接 ---一般都使用
            properties.put("mail.debug", "true");// 设置是否显示debug信息 true 会在控制台显示相关信息
            try {
                // 得到回话对象
                Session session = Session.getInstance(properties);
                // 获取邮件对象
                Message message = new MimeMessage(session);
                // 设置发件人邮箱地址
                message.setFrom(new InternetAddress(from));
                // 设置收件人邮箱地址
                //message.setRecipients(Message.RecipientType.TO, new InternetAddress[]{new InternetAddress(receive), new InternetAddress(receive), new InternetAddress(receive)});
                message.setRecipient(Message.RecipientType.TO, new InternetAddress(receive));//一个收件人
                // 设置邮件标题
                message.setSubject(subject);
                // 创建消息部分
                BodyPart messageBodyPart = new MimeBodyPart();
                // 消息
                messageBodyPart.setText(msg);
    
                // 创建多重消息
                Multipart multipart = new MimeMultipart();
    
                // 设置文本消息部分
                multipart.addBodyPart(messageBodyPart);
                // 发送完整消息
                message.setContent(multipart);
    
                // 得到邮差对象
                Transport transport = session.getTransport();
                // 连接自己的邮箱账户
                transport.connect(from, pass);// 密码为QQ邮箱开通的stmp服务后得到的客户端授权码
                // 发送邮件
                transport.sendMessage(message, message.getAllRecipients());
                transport.close();
                return true;
            } catch (MessagingException e) {
                e.printStackTrace();
            }
            return false;
        }
    
        /**
         * @param send 发送者邮箱
         * @param authCode 授权码
         * @param receive 接收者邮箱
         * @param subject 邮件主题
         * @param filename 本地附件
         * **/
        public static boolean send126Mail(String send, String authCode, String receive, String subject, String msg, String filename) {
            if (StringUtils.isEmpty(receive)) {
                return false;
            }
            // 发件人电子邮箱
            PasswordAuthentication passwordAuthentication = new PasswordAuthentication(send, authCode);
            // 指定发送邮件的主机为 smtp.126.com
            String host = "smtp.126.com"; // 邮件服务器
    
            // 获取系统属性
            Properties properties = System.getProperties();
            // 1. 创建参数配置, 用于连接邮件服务器的参数配置
            properties.put("mail.transport.protocol", "smtp");// 连接协议
            properties.setProperty("mail.smtp.host", host);
            //设 置 邮 件服 务 器 主 机 名
            properties.setProperty("mail.host", host);
            properties.put("mail.smtp.host", host);// 主机名
            properties.put("mail.smtp.port", 465);// 端口号
            properties.put("mail.smtp.auth", "true");
            properties.put("mail.smtp.ssl.enable", "true");// 设置是否使用ssl安全连接 ---一般都使用
            properties.put("mail.debug", "true");// 设置是否显示debug信息 true 会在控制台显示相关信息
            try {
                //开 启 S S L 加 密，否 则 会 失 败
                MailSSLSocketFactory sf = new MailSSLSocketFactory();
                sf.setTrustAllHosts(true);
                properties.put("mail.smtp.ssl.socketFactory", sf);
                //解决附件文件名过长的问题
                properties.put("mail.mime.splitlongparameters", "false");
                // 2. 根据配置创建会话对象, 用于和邮件服务器交互
                Session session = Session.getInstance(properties, new Authenticator() {
                    @Override
                    protected PasswordAuthentication getPasswordAuthentication() {
                        return passwordAuthentication;
                    }
                });
                session.setDebug(true);                                 // 设置为debug模式, 可以查看详细的发送 log
                // 3. 创建一封邮件
                Message message = new MimeMessage(session);
                // 设置发件人邮箱地址
                message.setFrom(new InternetAddress(send));
                // 设置收件人邮箱地址
                //message.setRecipients(Message.RecipientType.TO, new InternetAddress[]{new InternetAddress(receive), new InternetAddress(receive), new InternetAddress(receive)});
                message.setRecipient(Message.RecipientType.TO, new InternetAddress(receive));//一个收件人
                // 设置邮件标题
                message.setSubject(subject);
                // 创建消息部分
                BodyPart messageBodyPart = new MimeBodyPart();
                // 消息
                messageBodyPart.setText(msg);
    
                // 创建多重消息
                Multipart multipart = new MimeMultipart();
    
                // 设置文本消息部分
                multipart.addBodyPart(messageBodyPart);
    
                // 附件部分
                messageBodyPart = new MimeBodyPart();
                // 设置要发送附件的文件路径
                DataSource source = new FileDataSource(filename);
                messageBodyPart.setDataHandler(new DataHandler(source));
    
                // messageBodyPart.setFileName(filename);
                // 处理附件名称中文（附带文件路径）乱码问题
                messageBodyPart.setFileName(MimeUtility.encodeText(filename));
                multipart.addBodyPart(messageBodyPart);
    
                // 发送完整消息
                message.setContent(multipart);
    
                // 4. 根据 Session 获取邮件传输对象
                Transport transport = session.getTransport();
    
                // 5. 使用 邮箱账号 和 密码 连接邮件服务器, 这里认证的邮箱必须与 message 中的发件人邮箱一致, 否则报错
                //
                //    PS_01: 成败的判断关键在此一句, 如果连接服务器失败, 都会在控制台输出相应失败原因的 log,
                //           仔细查看失败原因, 有些邮箱服务器会返回错误码或查看错误类型的链接, 根据给出的错误
                //           类型到对应邮件服务器的帮助网站上查看具体失败原因。
                //
                //    PS_02: 连接失败的原因通常为以下几点, 仔细检查代码:
                //           (1) 邮箱没有开启 SMTP 服务;
                //           (2) 邮箱密码错误, 例如某些邮箱开启了独立密码;
                //           (3) 邮箱服务器要求必须要使用 SSL 安全连接;
                //           (4) 请求过于频繁或其他原因, 被邮件服务器拒绝服务;
                //           (5) 如果以上几点都确定无误, 到邮件服务器网站查找帮助。
                //
                //    PS_03: 仔细看log, 认真看log, 看懂log, 错误原因都在log已说明。
                transport.connect(passwordAuthentication.getUserName(), passwordAuthentication.getPassword());// 密码为126邮箱开通的stmp服务后得到的客户端授权码
                // 6. 发送邮件, 发到所有的收件地址, message.getAllRecipients() 获取到的是在创建邮件对象时添加的所有收件人, 抄送人, 密送人
                transport.sendMessage(message, message.getAllRecipients());
                // 7. 关闭连接
                transport.close();
                return true;
            } catch (MessagingException | UnsupportedEncodingException | GeneralSecurityException e) {
                e.printStackTrace();
            }
            return false;
        }
    
    }
    

2.  发送网易邮箱
    

同理先进入邮箱，申请SMTP授权码，**授权码一定要记住**  
测试代码：

    package com.java.mail.test;
    
    import com.java.mail.util.SendMailAcceUtils;
    
    public class Test {
        public static void main(String[] args) {
            SendMailAcceUtils.sendQQMailWithOutFile("xxx@outlook.com","testTemp","web3j");
            SendMailAcceUtils.send126Mail("xxx@126.com","xxxx","xxx@gmail.com","web3j","wexxxx",null);
        }
    }
    

* * *

总结
--

提示：亲测可用。  
项目放在github上，喜欢自取。地址:[https://github.com/ETCPark/JavaMail](https://github.com/ETCPark/JavaMail)

---

*Originally published on [jambestwick](https://paragraph.com/@vatalikbuterin/javamail-jamebestwick-csdn)*
