• Java发送(QQ)邮箱、验证码发送


    前言

    使用Java应用程序发送 E-mail 十分简单,但是首先需要在项目中导入 JavaMail API 和Java Activation Framework (JAF) 的jar包。

    菜鸟教程提供的下载链接:

    1、准备工作

    1.1 导包

    在基础Java工程中

    首先在项目目录下创建libs文件夹后将下载好的jar包复制进去,最后鼠标右击选择添加为库完成jar包的导入操作。

    image-20230909155449871

    如果是Maven工程,只需要导入相应的坐标即可。

    <dependency>
        <groupId>com.sun.mailgroupId>
        <artifactId>javax.mailartifactId>
        <version>1.6.2version>
    dependency>
    <dependency>
        <groupId>javax.activationgroupId>
        <artifactId>activationartifactId>
        <version>1.1.1version>
    dependency>
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10

    下面采用基础项目的方式展开。

    1.2 开启IMAP/SMTP服务

    以QQ邮箱为例

    image-20230909160347956

    QQ 邮箱通过生成授权码来设置密码:

    image-20230909160423496

    2、发送一篇简单的E-mail

    一些常用邮件服务商的SMTP信息:

    • QQ邮箱:SMTP服务器是smtp.qq.com,端口是465/587;
    • 163邮箱:SMTP服务器是smtp.163.com,端口是465;
    • Gmail邮箱:SMTP服务器是smtp.gmail.com,端口是465/587。

    2.1 连接

    通过JavaMail API连接到SMTP服务器上:

    // 收件人电子邮箱
    String to = "XXX@qq.com";
    
    // 发件人电子邮箱
    String from = "XXX@qq.com";
    
    //生成的授权码
    String password = "*******";
    
    // 指定发送邮件的主机为 smtp.qq.com
    String host = "smtp.qq.com";  //QQ 邮件服务器
    
    // 获取系统属性
    Properties properties = System.getProperties();
    
    // 设置邮件服务器
    properties.setProperty("mail.smtp.host", host);
    
    properties.put("mail.smtp.auth", "true");
    // 获取默认session对象
    Session session = Session.getDefaultInstance(properties,new Authenticator(){
        public PasswordAuthentication getPasswordAuthentication()
            {
                return new PasswordAuthentication(from, password); //发件人邮件用户名、授权码
             }
        });
    
    // 设置debug模式便于调试:
    session.setDebug(true);
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29

    2.2 发送

    发送邮件时,我们需要构造一个Message对象,然后调用Transport.send(Message)即可完成发送:

    // 创建默认的 MimeMessage 对象
    MimeMessage message = new MimeMessage(session);
    
    // Set From: 头部头字段
    message.setFrom(new InternetAddress(from));
    
    // Set To: 头部头字段
    message.addRecipient(Message.RecipientType.TO,new InternetAddress(to));
    
    // Set Subject: 头部头字段
    message.setSubject("这是邮件主题!","UTF-8");
    
    // 设置消息体
    message.setText("这是邮件正文","UTF-8");
    
    // 发送消息
    Transport.send(message);
    
    //发送完成后控制台打印输出
    System.out.println("Sent message successfully....");
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20

    2.3 完整写法

    // 文件名 SendEmail.java
    
    import java.util.*;
    import javax.mail.*;
    import javax.mail.internet.*;
    import javax.activation.*;
    
    public class SendEmail
    {
        public static void main(String [] args)
        {
           // 收件人电子邮箱
        String to = "XXX@qq.com";
    
        // 发件人电子邮箱
        String from = "XXX@qq.com";
    
        //生成的授权码
        String password = "*******";
    
        // 指定发送邮件的主机为 smtp.qq.com
        String host = "smtp.qq.com";  //QQ 邮件服务器
    
        // 获取系统属性
        Properties properties = System.getProperties();
    
        // 设置邮件服务器
        properties.setProperty("mail.smtp.host", host);
    
        properties.put("mail.smtp.auth", "true");
        // 获取默认session对象
        Session session = Session.getDefaultInstance(properties,new Authenticator(){
            public PasswordAuthentication getPasswordAuthentication()
                {
                    return new PasswordAuthentication(from, password); //发件人邮件用户名、授权码
                 }
            });
    
        // 设置debug模式便于调试:
        session.setDebug(true);
    
                try{
                   // 创建默认的 MimeMessage 对象
        MimeMessage message = new MimeMessage(session);
    
        // Set From: 头部头字段
        message.setFrom(new InternetAddress(from));
    
        // Set To: 头部头字段
        message.addRecipient(Message.RecipientType.TO,new InternetAddress(to));
    
        // Set Subject: 头部头字段
        message.setSubject("这是邮件主题!","UTF-8");
    
        // 设置消息体
        message.setText("这是邮件正文","UTF-8");
    
        // 发送消息
        Transport.send(message);
    
        //发送完成后控制台打印输出
        System.out.println("Sent message successfully....");
                }catch (MessagingException mex) {
                    mex.printStackTrace();
                }
            }
    }
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56
    • 57
    • 58
    • 59
    • 60
    • 61
    • 62
    • 63
    • 64
    • 65
    • 66
    • 67
    • 68

    如果你想发送一封e-mail给多个收件人,那么使用下面的方法来指定多个收件人ID:

    void addRecipients(Message.RecipientType type,Address[] addresses) throws MessagingException
    
    • 1

    下面是对于参数的描述:

    • **type:**要被设置为 TO, CC 或者 BCC,这里 CC 代表抄送、BCC 代表秘密抄送。举例:Message.RecipientType.TO
    • addresses: 这是 email ID 的数组。在指定电子邮件 ID 时,你将需要使用 InternetAddress() 方法。

    2.4 效果

    image-20230909161747223

    3、发送一封 HTML E-mail

    发送HTML邮件和文本邮件是类似的,只需要把:

    message.setText(body, "UTF-8");
    
    • 1

    改为:

    message.setText(body, "UTF-8", "html"); 
    
    • 1

    一般这个都是以发验证码的为主,所以我仿照Apifox做了个发验证码的页面vericode.html,做的不是很标准。😢

    image-20230909162500275

    3.1 HTML页面

    DOCTYPE html>
    <html lang="en">
    <head>
        <meta charset="UTF-8">
        <title>博客 邮箱验证码title>
        <style>
    
            .main {
                margin: 10px auto;
                width: 520px;
    
                border-top: 4px solid #9373EE;
                padding: 24px 24px 40px;
                border-radius:0 0 8px 8px;
                box-shadow: 0px 0px 1px;
            }
    
            .title {
                margin: 80px auto 32px;
                font-size: 32px;
                font-weight: 600;
                line-height: 45px;
                letter-spacing: 0px;
    
            }
    
            .note {
                margin: 0 auto;
                font-size: 18px;
                line-height: 1.4;
                left: 0px;
                top: 77px;
                font-weight: 400;
            }
    
            .code {
                padding: 16px;
                text-align: center;
                background: rgba(147, 115, 238, 0.04);
                border-radius: 4px;
                font-weight: 600;
                font-size: 24px;
                line-height: 140%;
                color: #9373EE;
                margin: 24px 0;
                letter-spacing: 1px;
            }
    
            .claim ul {
                margin-top: 34px;
                margin-bottom: 40px;
                font-size: 13px;
                line-height: 1.6;
                color: #5c5c5c;
                padding: 25px 0;
    
            }
    
            .claim ul li {
                color: rgba(24, 24, 25, 0.42);
                line-height: 30px;
            }
    
            .footer {
                font-size: 13px;
                line-height: 1.6;
                color: #5c5c5c;
                padding: 25px 0
            }
            .title,.note,.claim,.footer {
                text-align: center;
            }
        style>
    head>
    <body>
    <div class="main">
        <div class="title">博客 邮箱账号验证码div>
        <div class="note">你正在进行邮箱验证操作,验证码为:div>
        <div class="code" :data="123456">1EM456div>
    
        <div class="claim">
            <ul style="list-style: none;">
                <li style="list-style: none;">此验证码 15 分钟内有效li>
                <li style="list-style: none;">如非本人操作li>
                <li style="list-style: none;">转给他人将导致账号被盗和个人信息泄漏,谨防诈骗li>
            ul>
        div>
    
        <div class="footer">
            <a href="https://blog.csdn.net/qq_62254095?spm=1018.2226.3001.5343" target="_blank" style="color: #9373EE; text-decoration: none;">个人博客a> - 记录学习的每一分钟
        div>
    div>
    body>
    html>
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56
    • 57
    • 58
    • 59
    • 60
    • 61
    • 62
    • 63
    • 64
    • 65
    • 66
    • 67
    • 68
    • 69
    • 70
    • 71
    • 72
    • 73
    • 74
    • 75
    • 76
    • 77
    • 78
    • 79
    • 80
    • 81
    • 82
    • 83
    • 84
    • 85
    • 86
    • 87
    • 88
    • 89
    • 90
    • 91
    • 92
    • 93
    • 94

    3.2 完整写法

    // 文件名 SendHTMLEmail.java
    
    import java.util.*;
    import javax.mail.*;
    import javax.mail.internet.*;
    
    
    public class SendHTMLEmail
    {
        public static String vericodeHtml = "\n" +
                "\n" +
                "\n" +
                "    \n" +
                "    博客 邮箱验证码\n" +
                "    \n" +
                "\n" +
                "\n" +
                "
    \n" + "
    博客 邮箱账号验证码
    \n"
    + "
    你正在进行邮箱验证操作,验证码为:
    \n"
    + "
    1EM456
    \n"
    + "\n" + "
    \n" + "
      \n" + "
    • 此验证码 15 分钟内有效
    • \n"
      + "
    • 如非本人操作
    • \n"
      + "
    • 转给他人将导致账号被盗和个人信息泄漏,谨防诈骗
    • \n"
      + "
    \n"
    + "
    \n"
    + "\n" + "
    \n" + " 个人博客 - 记录学习的每一分钟\n" + "
    \n"
    + "
    \n"
    + "\n" + ""; public static void main(String [] args) { // 收件人电子邮箱 String to = "XXX@qq.com"; // 发件人电子邮箱 String from = "XXX@qq.com"; // 生成的授权码 String password = "XXXX"; // 指定发送邮件的主机为 smtp.qq.com String host = "smtp.qq.com"; //QQ 邮件服务器 // 获取系统属性 Properties properties = System.getProperties(); // 设置邮件服务器 properties.setProperty("mail.smtp.host", host); properties.put("mail.smtp.auth", "true"); // 获取默认的 Session 对象。 // 获取默认session对象 Session session = Session.getDefaultInstance(properties,new Authenticator(){ public PasswordAuthentication getPasswordAuthentication() { return new PasswordAuthentication(from, password); //发件人邮件用户名、授权码 } }); // 设置debug模式便于调试: session.setDebug(true); try{ // 创建默认的 MimeMessage 对象。 MimeMessage message = new MimeMessage(session); // Set From: 头部头字段 message.setFrom(new InternetAddress(from)); // Set To: 头部头字段 message.addRecipient(Message.RecipientType.TO, new InternetAddress(to)); // Set Subject: 头字段 message.setSubject("HTML邮箱验证码2","UTF-8"); // 发送 HTML 消息, 可以插入html标签 String generatedCode = "B12ACD"; // 假设后台生成的验证码 String emailBody = vericodeHtml.replace(":data=\"123456\"", ":data=\"" + generatedCode + "\"").replace("1EM456", generatedCode); //将发送页面的验证码改为后台生成的验证码 message.setText(emailBody, "UTF-8", "html"); // 发送消息 Transport.send(message); System.out.println("Sent message successfully...."); }catch (MessagingException mex) { mex.printStackTrace(); } } }
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56
    • 57
    • 58
    • 59
    • 60
    • 61
    • 62
    • 63
    • 64
    • 65
    • 66
    • 67
    • 68
    • 69
    • 70
    • 71
    • 72
    • 73
    • 74
    • 75
    • 76
    • 77
    • 78
    • 79
    • 80
    • 81
    • 82
    • 83
    • 84
    • 85
    • 86
    • 87
    • 88
    • 89
    • 90
    • 91
    • 92
    • 93
    • 94
    • 95
    • 96
    • 97
    • 98
    • 99
    • 100
    • 101
    • 102
    • 103
    • 104
    • 105
    • 106
    • 107
    • 108
    • 109
    • 110
    • 111
    • 112
    • 113
    • 114
    • 115
    • 116
    • 117
    • 118
    • 119
    • 120
    • 121
    • 122
    • 123
    • 124
    • 125
    • 126
    • 127
    • 128
    • 129
    • 130
    • 131
    • 132
    • 133
    • 134
    • 135
    • 136
    • 137
    • 138
    • 139
    • 140
    • 141
    • 142
    • 143
    • 144
    • 145
    • 146
    • 147
    • 148
    • 149
    • 150
    • 151
    • 152
    • 153
    • 154
    • 155
    • 156
    • 157
    • 158
    • 159
    • 160
    • 161
    • 162
    • 163
    • 164
    • 165
    • 166
    • 167
    • 168

    **建议:**可以生成一个类专门用来存放String类型的HTML模板,需要用时再导入,这样比较优雅( ̄︶ ̄)↗

    3.3 效果图

    image-20230909163815145

    4、发送带有附件的 E-mail

    要在电子邮件中携带附件,我们就不能直接调用message.setText()方法,而是要构造一个Multipart对象:

    Multipart multipart = new MimeMultipart();
    // 添加text:
    BodyPart textpart = new MimeBodyPart();
    textpart.setContent(body, "text/html;charset=utf-8");
    multipart.addBodyPart(textpart);
    // 添加image:
    BodyPart imagepart = new MimeBodyPart();
    imagepart.setFileName(fileName);
    imagepart.setDataHandler(new DataHandler(new ByteArrayDataSource(input, "application/octet-stream")));
    multipart.addBodyPart(imagepart);
    // 设置邮件内容为multipart:
    message.setContent(multipart);
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12

    一个Multipart对象可以添加若干个BodyPart,其中第一个BodyPart是文本,即邮件正文,后面的BodyPart是附件。BodyPart依靠setContent()决定添加的内容。

    • 如果添加文本,、

      setContent("...","text/plain;charset=utf-8")添加纯文本,

      或者用setContent("...","text/html;charset=utf-8")添加HTML文本。

    • 如果添加附件,

      需要设置文件名(不一定和真实文件名一致),并且添加一个DataHandler(),传入文件的MIME类型。二进制文件可以用application/octet-stream,Word文档则是application/msword

    最后,通过setContent()Multipart添加到Message中,即可发送。

    4.1 完整写法

    // 文件名 SendFileEmail.java
    import java.io.File;
    import java.util.*;
    import javax.mail.*;
    import javax.mail.internet.*;
    import javax.activation.*;
    
    
    public class SendFileEmail {
        public static void main(String[] args) {
    
            // 收件人电子邮箱
            String to = "XXX@qq.com";
    
            // 发件人电子邮箱
            String from = "XXX@qq.com";
    
            String password = "*****";
    
            // 指定发送邮件的主机为 smtp.qq.com
            String host = "smtp.qq.com";  //QQ 邮件服务器
    
            // 获取系统属性
            Properties properties = System.getProperties();
    
            // 设置邮件服务器
            properties.setProperty("mail.smtp.host", host);
    
            properties.put("mail.smtp.auth", "true");
            // 获取默认session对象
            Session session = Session.getDefaultInstance(properties, new Authenticator() {
                public PasswordAuthentication getPasswordAuthentication() {
                    return new PasswordAuthentication(from, password); //发件人邮件用户名、授权码
                }
            });
            session.setDebug(true);
            try {
                // 创建默认的 MimeMessage 对象。
                MimeMessage message = new MimeMessage(session);
    
                // Set From: 头部头字段
                message.setFrom(new InternetAddress(from));
    
                // Set To: 头部头字段
                message.addRecipient(Message.RecipientType.TO,
                        new InternetAddress(to));
    
                // Set Subject: 头字段
                message.setSubject("附件发送");
    
                // 创建消息部分
                MimeBodyPart messageBodyPart = new MimeBodyPart();
                messageBodyPart.setContent("

    Hello

    这是一封带有附件的Javamail邮箱"
    , "text/html;charset=utf-8"); // 创建附件部分 MimeBodyPart attachmentPart = new MimeBodyPart(); // 使用绝对路径查找文件,直接从项目名开始 String filePath = "java-email/src/kun.jpg"; File file = new File(filePath); FileDataSource fds = new FileDataSource(file); attachmentPart.setDataHandler(new DataHandler(fds)); //attachmentPart.setDataHandler(new DataHandler(new ByteArrayDataSource(input, "application/octet-stream"))); attachmentPart.setFileName(file.getName()); // 创建多部分消息 Multipart multipart = new MimeMultipart(); multipart.addBodyPart(messageBodyPart); multipart.addBodyPart(attachmentPart); // 设置邮件内容为multipart: message.setContent(multipart); // 发送消息 Transport.send(message); System.out.println("Sent message successfully...."); } catch (MessagingException mex) { mex.printStackTrace(); } } }
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56
    • 57
    • 58
    • 59
    • 60
    • 61
    • 62
    • 63
    • 64
    • 65
    • 66
    • 67
    • 68
    • 69
    • 70
    • 71
    • 72
    • 73
    • 74
    • 75
    • 76
    • 77
    • 78
    • 79
    • 80
    • 81
    • 82
    • 83
    • 84
    • 85

    4.2 效果图

    image-20230909173655230

    4.3 目录结构

    image-20230909173713673

    注意:

    • Maven项目也跟上面相差不大,也可以自己写个工具类简化开发,或者找其他人写好的

    • 发送附件时使用绝对路径,是因为我在使用相对路径是有些错误,找不到文件,不清楚为什么

    • 有知道的大神可以评论给出答案🙂,也欢迎各位找错补充👍

  • 相关阅读:
    JavaScript中常用的事件
    FreeRTOS 事件标志组 详解
    C++ ACM
    【复杂网络建模】——链路预测算法及其应用
    爬虫使用什么库更事半功倍?
    Vuex
    echarts图表坐标轴数据标签添加下划线
    mysql经典案例带解析(你没见过的全新版本)55题
    kibana报错和重定向次数过多
    网络资源的源码如何查看?电脑PC推荐安装的软件(pdf编辑工具、浏览器、杀毒软件、办公软件、压缩工具等等)
  • 原文地址:https://blog.csdn.net/qq_62254095/article/details/132780318