┌─────────┐ ┌─────────┐ ┌─────────┐ │?????????│ │?????????│ │?????????│ ┌───────┐ ├─────────┤ ├─────────┤ ├─────────┤ ┌───────┐ │???????│ │?????????│ │?????????│ │?????????│ │???????│ ├───────┤ ├─────────┤ ├─────────┤ ├─────────┤ ├───────┤ │ │───>│O ???????│───>│O ???????│───>│O ???????│<───│ │ └───────┘ └─────────┘ └─────────┘ └─────────┘ └───────┘ MUA MTA MTA MDA MUA
常用的邮件服务提供商SMTP信息: ●QQ邮箱:SMTP服务器是smtp.qq.com,端口是465/587 ●163邮箱:SMTP服务器是smtp.163.com,端口是465 ●126邮箱:SMTP服务器是smtp.126.com,端口是25 ●Gmail邮箱:SMTP服务器是smtp.gmail.com,端口是465/587
准备好SMTP登录信息后,我们必须首先检查JavaMail相关的依赖Jar包javax.mail-1.6.2.jar加入当前项目。(相关。jar包在我上传的资源中)
// SMTP服务器地址 String smtp = "smtp.163.com"; ///邮箱账号和密码(授权密码) String userName = "zf5209926@163.com"; String password = "***FLMDZTIROSCL"; 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 // 参数1:SMTP连接服务器的信息 // 参数2: 用户认证对象(Authenticator匿名实现类接口) Session session = Session.getInstance(props, new Authenticator() { @Override protected PasswordAuthentication getPasswordAuthentication() { return new PasswordAuthentication(userName,password); } }); // 打开调试模式 session.setDebug(true);
发送HTML邮件
发送邮件时,我们需要构造一个Message对象,然后调用Transport.send(Message)可完成发送:绝大多数邮件服务器要求发送方地址与登录用户名一致,否则发送将失败。
try { Session session = JavaMailUtils.createSession(); String text = "我来自于蛮荒,直至存活至公元<b>2111</b>年,这是给过去的我的"; // 2.创建邮件对象(Message抽象子类对象) MimeMessage msg = new MimeMessage(session); // 传入session对象 msg.setFrom(new InternetAddress("zf5209926@163.com")); // 发件人 msg.setRecipient(RecipientType.TO, new InternetAddress("***4318***@qq.com")); // 收件人 msg.setSubject("你来自未来", "utf-8"); // 标题 msg.setText(text, "utf-8", "html"); // 正文 // 3.发送邮件 Transport.send(msg); } catch (MessagingException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
msg.setText(text, "utf-8", "html"); // 设置以html格式发送
然后运行上述代码块,我们可以在控制台看到JavaMail打印的调试信息:
DEBUG: setDebug: JavaMail version 1.6.2
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.163.com, user=王智博, password=<null>
DEBUG SMTP: useEhlo true, useAuth true
DEBUG SMTP: trying to connect to host "smtp.163.com", port 25, isSSL false
220 163.com Anti-spam GT for Coremail System (163com[20141201])
DEBUG SMTP: connected to host "smtp.163.com", port: 25
EHLO DESKTOP-LP308OO
250-mail
250-PIPELINING
250-AUTH LOGIN PLAIN XOAUTH2
250-AUTH=LOGIN PLAIN XOAUTH2
250-coremail 1Uxr2xKj7kG0xkI17xGrU7I0s8FY2U3Uj8Cz28x1UUUUU7Ic2I0Y2UFz4Li7UCa0xDrUUUUj
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 "1Uxr2xKj7kG0xkI17xGrU7I0s8FY2U3Uj8Cz28x1UUUUU7Ic2I0Y2UFz4Li7UCa0xDrUUUUj"
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 DESKTOP-LP308OO
250-mail
250-PIPELINING
250-AUTH LOGIN PLAIN XOAUTH2
250-AUTH=LOGIN PLAIN XOAUTH2
250-coremail 1Uxr2xKj7kG0xkI17xGrU7I0s8FY2U3Uj8Cz28x1UUUUU7Ic2I0Y2UrxLpU0UCa0xDrUUUUj
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 "1Uxr2xKj7kG0xkI17xGrU7I0s8FY2U3Uj8Cz28x1UUUUU7Ic2I0Y2UrxLpU0UCa0xDrUUUUj"
DEBUG SMTP: Found extension "STARTTLS", arg ""
DEBUG SMTP: Found extension "ID", arg ""
DEBUG SMTP: Found extension "8BITMIME", arg ""
DEBUG SMTP: protocolConnect login, host=smtp.163.com, user=zf5209926@163.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:<zf5209926@163.com>
250 Mail OK
RCPT TO:<*******@qq.com>
250 Mail OK
DEBUG SMTP: Verified Addresses
DEBUG SMTP: *******@qq.com
DATA
354 End data with <CR><LF>.<CR><LF>
Date: Sun, 17 Jul 2022 18:11:08 +0800 (CST)
From: zf5209926@163.com
To: *******@qq.com
Message-ID: <1585787493.0.1658052668941@DESKTOP-LP308OO>
Subject: =?utf-8?B?5p2l6Ieq5pyq5p2l55qE5L2g?=
MIME-Version: 1.0
Content-Type: text/html; charset=utf-8
Content-Transfer-Encoding: base64
5oiR5p2l6Ieq5LqO6Juu6I2S77yM55u06Iez5a2Y5rS76Iez5YWs5YWDPGI+MjExMTwvYj7lubTv
vIzov5nmmK/lj5Hnu5nov4fljrvnmoTmiJE=
.
250 Mail OK queued as smtp9,DcCowACHWy094NNid5E6QA--.58681S3 1658052672
DEBUG SMTP: message successfully delivered to mail server
QUIT
221 Bye
当出现则代表发送成功
发送附件
要在电子邮件中携带附件,我们就不能直接调用message.setText()方法,而是要构造一个Multipart对象:
try {
Session session = JavaMailUtils.createSession();
String text = "我来自于蛮荒,直至存活至公元<b>2111</b>年,这是发给过去的我";
// 2.创建邮件对象(Message抽象类的子类对象)
MimeMessage msg = new MimeMessage(session); // 传入session对象
msg.setFrom(new InternetAddress("zf5209926@163.com")); // 发件人
msg.setRecipient(RecipientType.TO, new InternetAddress("********@qq.com")); // 收件人
msg.setSubject("来自未来的你", "utf-8"); // 标题
// 邮件内容"复合"对象
Multipart multipart = new MimeMultipart();
// 正文
BodyPart textPart = new MimeBodyPart();
// 参数1:正文内容
// 参数2: 内容类型 ; 字符编码集
textPart.setContent(text, "text/html;charset=utf-8");
// 附件
BodyPart imagePart = new MimeBodyPart();
imagePart.setFileName("WSY.jpg");
// 数据处理对象()
imagePart.setDataHandler(new DataHandler(
new ByteArrayDataSource(Files.readAllBytes(Paths.get("C:\\Users\\王智博\\Pictures\\Saved Pictures\\ya.jpg")),
"application/octet-stream")));
// 添加至邮件内容
multipart.addBodyPart(textPart); // 添加正文
multipart.addBodyPart(imagePart); // 添加附件
// 设置邮件内容
msg.setContent(multipart);
Transport.send(msg);
} catch (MessagingException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
可以理解为将正文和附件分别先存入BodyPart对象中,然后在使用Multipart对象将其合并打包给MimeMessage,然后发送即可。
发送内嵌图片的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);
这样就可以实现内嵌图片的发送