0


基于Java Email的邮件发送

当我们想了解电子邮件的发送时,我们先来看一下传统的邮件是如何发送的:传统的邮件是通过邮局投递,然后从一个邮局到另一个邮局,最终到达用户的邮箱。

           ┌──────────┐    ┌──────────┐
           │PostOffice│    │PostOffice│     .───.
┌─────┐    ├──────────┤    ├──────────┤    (   ( )
│═══ ░│───>│ ┌─┐ ┌┐┌┐ │───>│ ┌─┐ ┌┐┌┐ │───> `─┬─'
└─────┘    │ │░│ └┘└┘ │    │ │░│ └┘└┘ │       │
           └─┴─┴──────┘    └─┴─┴──────┘       │

电子邮件的发送过程也是类似的,只不过是电子邮件是从用户电脑的邮件软件,例
如Outlook,发送到邮件服务器上,可能经过若干个邮件服务器的中转,最终到达对方邮件服务器上,收件方就可以用软件接收邮件。

             ┌─────────┐    ┌─────────┐    ┌─────────┐
             │░░░░░░░░░│    │░░░░░░░░░│    │░░░░░░░░░│
┌───────┐    ├─────────┤    ├─────────┤    ├─────────┤    ┌───────┐
│░░░░░░░│    │░░░░░░░░░│    │░░░░░░░░░│    │░░░░░░░░░│    │░░░░░░░│
├───────┤    ├─────────┤    ├─────────┤    ├─────────┤    ├───────┤
│       │───>│O ░░░░░░░│───>│O ░░░░░░░│───>│O ░░░░░░░│<───│       │
└───────┘    └─────────┘    └─────────┘    └─────────┘    └───────┘
   MUA           MTA            MTA            MDA           MUA

邮件软件称为MUA :Mail User Agent:给用户服务的邮件代理:

邮件服务器则称为MTA: Mai1 Transfer Agent,意思是邮件中转的代理

最终到达的邮件服务器称为MDA : Mail Delivery Agent,意思是邮件到达的代理。

电子邮件一旦到达MDA,就不再动了。实际上,电子邮件通常就存储在MDA服务器的硬盘上,然后等收件人通过软件或者登陆浏览器查看邮件。

SMTP协议

SMTP的全称“SimpleMailTransferProtocol”,即简单邮件传输协议。它是一组用于从源地址到目的地址传输邮件的规范,通过它来控制邮件的中转方式。SMTP协议属于TCP/IP协议簇,它帮助每台计算机在发送或中转信件时找到下一个目的地。SMTP服务器就是遵循SMTP协议的发送邮件服务器。SMTP认证,简单地说就是要求必须在提供了账户名和密码之后才可以登录SMTP服务器,这就使得那些垃圾邮件的散播者无可乘之机。增加SMTP认证的目的是为了使用户避免受到垃圾邮件的侵扰。

IMAP协议

IMAP全称是Internet MailAccessProtocol,即交互式邮件存取协议,它是跟POP3类似邮件访问标准协议之一。不同的是,开启了IMAP后,您在电子邮件客户端收取的邮件仍然保留在服务器上,同时在客户端上的操作都会反馈到服务器上,如:删除邮件,标记已读等,服务器上的邮件也会做相应的动作。所以无论从浏览器登录邮箱或者客户端软件登录邮箱,看到的邮件以及状态都是一致的。

IMAP和POP3有什么区别?
POP3协议允许电子邮件客户端下载服务器上的邮件,但是在客户端的操作(如移动邮件、标记已读等),不会反馈到服务器上,比如通过客户端收取了邮箱中的3封邮件并移动到其他文件夹,邮箱服务器上的这些邮件是没有同时被移动的。

IMAP提供webmail与电子邮件客户端之间的双向通信,客户端的操作都会反馈到服务器上,对邮件进行的操作,服务器上的邮件也会做相应的动作。

准备SMTP登录信息

假设我们准备使用自己的邮件地址发送邮件,在发送邮件前,我们首先要确定作为MTA的邮件服务器地址和端口号,邮件服务器的地址通常是smtp.***.com,端口号由邮件服务商确定。接着,我虚需要将JavaMail相关的依赖jar包加入到当前项目。

    然后我们通过JavaMail API连接到SMTP服务器上,连接SMTP服务器时,需要准备一个Properties对象,填入相关信息,最后获取Session实例,如果服务器需要认证,还需传入一个 Authenticator对象,并返回指定的用户名和口令。当我们获取到Session实例后,打开debug模式便于我们查看SMTP通信的详细内容。
// 服务器地址:
String smtp = "smtp.126.com";

// 登录用户名:
String username = "[email protected]";

// 登录口令:
String password = "***************";

// 连接到SMTP服务器25端口:
Properties props = new Properties();
props.put("mail.smtp.host", smtp); // SMTP主机名
props.put("mail.smtp.port", "25"); // 主机端口号
props.put("mail.smtp.auth", "true"); // 是否需要用户认证
props.put("mail.smtp.starttls.enable", "true"); // 启用TLS加密

// 获取Session实例:
Session session = Session.getInstance(props, new Authenticator() {
    protected PasswordAuthentication getPasswordAuthentication() {
        return new PasswordAuthentication(username, password);
    }
});
// 设置debug模式便于调试:
session.setDebug(true);

发送邮件
发送邮件时,我们需要构造一个 Message对
象,然后调用 Transport.send(Message)即可完成发送:绝大多数邮件服务器要求发送方地址和登录用户名必须一致,否则发送将失败。

try {
    MimeMessage message = new MimeMessage(session);
    // 设置发送方地址:
    message.setFrom(new InternetAddress("[email protected]"));
    // 设置接收方地址:
    message.setRecipient(Message.RecipientType.TO, new InternetAddress("[email protected]"));
    // 设置邮件主题:
    message.setSubject("Hello", "UTF-8");
    // 设置邮件正文:
    message.setText("Hi Xiaoming...", "UTF-8");
    // 发送:
    Transport.send(message);
} catch (AddressException e) {
    e.printStackTrace();
} catch (MessagingException e) {
    e.printStackTrace();
}

运行上边代码后,我们可以在控制台看到JavaMail打印的调试信息:

DEBUG: setDebug: JavaMail version 1.6.2
javax.mail.Session@2f0e140b
DEBUG: getProvider() returning javax.mail.Provider[TRANSPORT,smtp,com.sun.mail.smtp.SMTPTransport,Oracle]
DEBUG SMTP: need username and password for authentication
DEBUG SMTP: protocolConnect returning false, host=smtp.126.com, user=Administrator, password=<null>
DEBUG SMTP: useEhlo true, useAuth true
DEBUG SMTP: trying to connect to host "smtp.126.com", port 25, isSSL false
220 126.com Anti-spam GT for Coremail System (126com[20140526])
DEBUG SMTP: connected to host "smtp.126.com", port: 25
EHLO WIN-Q3DC0C93PPH
250-mail
250-PIPELINING
250-AUTH LOGIN PLAIN XOAUTH2
250-AUTH=LOGIN PLAIN XOAUTH2
250-coremail 1Uxr2xKj7kG0xkI17xGrU7I0s8FY2U3Uj8Cz28x1UUUUU7Ic2I0Y2UF2Mot0UCa0xDrUUUUj
250-STARTTLS
250-ID
250 8BITMIME
DEBUG SMTP: Found extension "PIPELINING", arg ""
DEBUG SMTP: Found extension "AUTH", arg "LOGIN PLAIN XOAUTH2"
DEBUG SMTP: Found extension "AUTH=LOGIN", arg "PLAIN XOAUTH2"
DEBUG SMTP: Found extension "coremail", arg "1Uxr2xKj7kG0xkI17xGrU7I0s8FY2U3Uj8Cz28x1UUUUU7Ic2I0Y2UF2Mot0UCa0xDrUUUUj"
DEBUG SMTP: Found extension "STARTTLS", arg ""
DEBUG SMTP: Found extension "ID", arg ""
DEBUG SMTP: Found extension "8BITMIME", arg ""
STARTTLS
220 Ready to start TLS
EHLO WIN-Q3DC0C93PPH
250-mail
250-PIPELINING
250-AUTH LOGIN PLAIN XOAUTH2
250-AUTH=LOGIN PLAIN XOAUTH2
250-coremail 1Uxr2xKj7kG0xkI17xGrU7I0s8FY2U3Uj8Cz28x1UUUUU7Ic2I0Y2UF4nVroUCa0xDrUUUUj
250-STARTTLS
250-ID
250 8BITMIME
DEBUG SMTP: Found extension "PIPELINING", arg ""
DEBUG SMTP: Found extension "AUTH", arg "LOGIN PLAIN XOAUTH2"
DEBUG SMTP: Found extension "AUTH=LOGIN", arg "PLAIN XOAUTH2"
DEBUG SMTP: Found extension "coremail", arg "1Uxr2xKj7kG0xkI17xGrU7I0s8FY2U3Uj8Cz28x1UUUUU7Ic2I0Y2UF4nVroUCa0xDrUUUUj"
DEBUG SMTP: Found extension "STARTTLS", arg ""
DEBUG SMTP: Found extension "ID", arg ""
DEBUG SMTP: Found extension "8BITMIME", arg ""
DEBUG SMTP: protocolConnect login, host=smtp.126.com, user=tm2837047212@126.com, password=<non-null>
DEBUG SMTP: Attempt to authenticate using mechanisms: LOGIN PLAIN DIGEST-MD5 NTLM XOAUTH2
DEBUG SMTP: Using mechanism LOGIN
DEBUG SMTP: AUTH LOGIN command trace suppressed
DEBUG SMTP: AUTH LOGIN succeeded
DEBUG SMTP: use8bit false
MAIL FROM:xxxxxxxxxxxxx@126.com
250 Mail OK
RCPT TO:xxxxxxxxxxx@qq.com
250 Mail OK
DEBUG SMTP: Verified Addresses
DEBUG SMTP: xxxxxxxxxxxxx@qq.com
DATA
354 End data with <CR><LF>.<CR><LF>
Date: Sun, 17 Jul 2022 17:49:09 +0800 (CST)
From: tm2837047212@126.com
To: 2837047212@qq.com
Message-ID: <500977346.0.1658051349834@WIN-Q3DC0C93PPH>
Subject: =?utf-8?B?6L+Z5piv5LiA5Lu95rWL6K+V5paH5Lu2?=
MIME-Version: 1.0
Content-Type: text/html; charset=utf-8
Content-Transfer-Encoding: base64

54ix5L2g5LiN5Y+Y55qE5qih5qC3ISznpZ3kvaDotbDnmoTlvog8Yj7lronor6Y8L2I+
.
250 Mail OK queued as smtp7,DsmowAA3evmi2tNikQ+LFA--.52235S3 1658051237
DEBUG SMTP: message successfully delivered to mail server
QUIT
221 Bye

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

// 创建MimeMessage邮件信息对象
// ...略

// 创建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(附件名称);
imagepart.setDataHandler(new DataHandler(new ByteArrayDataSource(文件流字节数组, "application/octet-stream")));
multipart.addBodyPart(imagepart);

// 设置邮件内容为multipart:
message.setContent(multipart);

一个Multipart对象可以添加若干个BodyP art,其中第一个BodyPart是文本,即邮件正文,后面的BodyPart是附件。BodyPart依靠setContent()决定添加的内容,如果添加文本,用 setContent(". "text/plain;char set=utf-8")添加纯文本,或者用 setContent("...","text/html;charset=utf-8")添加HTML 文本。如果添加附件,需要设置文件名(不一定和真实文件名一致),并且添加一个DataHa ndler(),传入文件的MIME类型。二进制文用 application/octet-stream,Word文档则是application/msword。最后,通过setContent()把Multipart添加到Message 中,即可发送。

发送内嵌图片的HTML邮件
如果需要在HTML邮件中内嵌图片,可以选择在邮件中加入< img src="http://example.com
test.jpg">,这样的外部图片链接通常会被邮件客户端过滤,并提示用户显示图片并不安全。只有内嵌的图片才能正常在邮件中显示。所以,这种方式并不推荐。推荐将内嵌图片作为一个附件嵌入邮件,即邮件本身也是Multipart,但需要做一点额外的处理。

// 创建MimeMessage邮件信息对象
// ...略

// 创建Multipart复合对象
Multipart multipart = new MimeMultipart();
                    
// 添加text:
BodyPart textpart = new MimeBodyPart();
textpart.setContent("<h1>Hello</h1><p><img src=\"cid:img01\"></p>", "text/html;charset=utf-8");
multipart.addBodyPart(textpart);

// 添加image:
BodyPart imagepart = new MimeBodyPart();
imagepart.setFileName("lvjuren.jpg");
imagepart.setDataHandler(new DataHandler(new ByteArrayDataSource(文件流字节数组, "application/octet-stream")));

// 设置当前image为内嵌图片
// 这个ID和HTML中引用的ID对应起来,邮件客户端就可以正常显示内嵌图片
imagepart.setHeader("Content-ID", "<img01>");

multipart.addBodyPart(imagepart);

本文转载自: https://blog.csdn.net/m0_66947503/article/details/125833723
版权归原作者 明天要早起~ 所有, 如有侵权,请联系我们删除。

“基于Java Email的邮件发送”的评论:

还没有评论