1. 概述
本文将介绍如何使用 Java 核心邮件库发送邮件,包括带附件和不带附件的场景。我们将通过实际代码演示关键操作,帮助开发者快速掌握邮件发送功能。
2. 项目设置与依赖
我们使用基于 Maven 的项目,并引入 Angus Mail 作为依赖。这是 Jakarta Mail API 规范的 Eclipse 实现:
<dependency>
<groupId>org.eclipse.angus</groupId>
<artifactId>angus-mail</artifactId>
<version>2.0.1</version>
</dependency>
最新版本可在 Maven 仓库 查询。
3. 发送纯文本与 HTML 邮件
首先需要配置邮件服务提供商的凭据,然后创建用于构建邮件的 Session
对象。配置通过 Java Properties
对象完成:
Properties prop = new Properties();
prop.put("mail.smtp.auth", true);
prop.put("mail.smtp.starttls.enable", "true");
prop.put("mail.smtp.host", "sandbox.smtp.mailtrap.io");
prop.put("mail.smtp.port", "25");
prop.put("mail.smtp.ssl.trust", "sandbox.smtp.mailtrap.io");
⚠️ 注意:以上配置使用了 Mailtrap 的测试服务。实际使用时需根据服务商文档调整主机地址(不同 SMTP 集成方式主机可能不同)。
接下来使用用户名密码创建会话:
Session session = Session.getInstance(prop, new Authenticator() {
@Override
protected PasswordAuthentication getPasswordAuthentication() {
return new PasswordAuthentication("your_username", "your_password");
}
});
现在创建邮件消息并发送:
Message message = new MimeMessage(session);
message.setFrom(new InternetAddress("[email protected]"));
message.setRecipients(
Message.RecipientType.TO, InternetAddress.parse("[email protected]"));
message.setSubject("邮件主题");
String msg = "这是使用 JavaMailer 发送的第一封邮件";
MimeBodyPart mimeBodyPart = new MimeBodyPart();
mimeBodyPart.setContent(msg, "text/html; charset=utf-8");
Multipart multipart = new MimeMultipart();
multipart.addBodyPart(mimeBodyPart);
message.setContent(multipart);
Transport.send(message);
核心逻辑说明:
- 创建消息对象并设置发件人、收件人、主题
- 创建
MimeBodyPart
存储正文(使用 HTML 编码) - 用
MimeMultipart
包装正文部分 - 将
multipart
设置为消息内容并发送
关键点: MimeBodyPart
被包含在消息的 multipart
中,而一个 multipart
可以包含多个 MimeBodyPart
(下一节将利用此特性添加附件)。
4. 发送带附件的邮件
添加附件只需创建额外的 MimeBodyPart
并附加文件:
MimeBodyPart attachmentBodyPart = new MimeBodyPart();
attachmentBodyPart.attachFile(new File("path/to/file"));
然后将新部件添加到之前创建的 MimeMultipart
对象:
multipart.addBodyPart(attachmentBodyPart);
就这么简单! 最后设置 multipart
为消息内容并调用 send()
发送邮件即可。
5. 格式化邮件文本
使用 HTML 和 CSS 标签可美化邮件内容。例如:
- 使用
<b>
标签加粗文本 - 通过
style
属性设置颜色 - 组合 HTML 与 CSS 实现复杂样式
示例代码(创建红色粗体文本):
String msgStyled = "这是我的 <b style='color:red;'>红色粗体邮件</b> 使用 JavaMailer";
此字符串将作为邮件正文发送。
6. 发送邮件给多个收件人
使用 setRecipients()
或 addRecipients()
方法可设置多个收件人,支持 TO
、CC
、BCC
类型。
6.1. 使用 setRecipients()
通过收件人数组设置:
Address[] recipients = new InternetAddress[2];
recipients[0] = new InternetAddress("[email protected]");
recipients[1] = new InternetAddress("[email protected]");
message.setRecipients(Message.RecipientType.TO, recipients);
或使用 InternetAddress.parse()
解析 CSV 格式地址:
message.setRecipients(Message.RecipientType.TO,
InternetAddress.parse("[email protected], [email protected]"));
6.2. 使用 addRecipients()
与 setRecipients()
的区别:
setRecipients()
会覆盖已有收件人列表addRecipients()
在现有列表基础上追加
示例(追加收件人):
Address[] newRecipients = new InternetAddress[2];
newRecipients[0] = new InternetAddress("[email protected]");
newRecipients[1] = new InternetAddress("[email protected]");
message.addRecipients(Message.RecipientType.TO, newRecipients);
同样支持 CSV 解析:
message.addRecipients(Message.RecipientType.TO,
InternetAddress.parse("[email protected], [email protected]"));
7. 设置连接超时
处理邮件服务时需防范网络问题,特别是服务器响应慢或不可达的情况。通过以下属性配置超时:
prop.put("mail.smtp.connectiontimeout", "10000"); // 连接超时(毫秒)
prop.put("mail.smtp.timeout", "10000"); // 读取超时
prop.put("mail.smtp.writetimeout", "10000"); // 写入超时
超时参数说明:
mail.smtp.connectiontimeout
:建立 SMTP 连接的等待时间mail.smtp.timeout
:从服务器读取数据的等待时间mail.smtp.writetimeout
:向服务器写入数据的等待时间
设置后,当 SMTP 服务器无响应时应用不会无限期挂起。
8. 忽略服务器证书错误
开发环境中遇到自签名证书或测试证书时,可通过以下配置跳过证书验证:
prop.put("mail.smtp.ssl.trust", "*"); // 信任所有证书
prop.put("mail.smtp.ssl.checkserveridentity", false); // 禁用服务器身份检查
对于 SMTPS 协议,仅设置 mail.smtp.ssl.trust="*"
可能不够,需自定义 SSLSocketFactory
:
// 创建信任所有证书的 TrustManager
TrustManager[] trustAllCerts = new TrustManager[]{
new X509TrustManager() {
public void checkClientTrusted(X509Certificate[] certs, String authType) {}
public void checkServerTrusted(X509Certificate[] certs, String authType) {}
public X509Certificate[] getAcceptedIssuers() {
return new X509Certificate[0];
}
}
};
// 初始化 SSL 上下文
SSLContext sslContext = SSLContext.getInstance("TLS");
sslContext.init(null, trustAllCerts, new java.security.SecureRandom());
SSLSocketFactory sslSocketFactory = sslContext.getSocketFactory();
// 设置自定义 Socket Factory
props.put("mail.smtp.ssl.enable", "true");
props.put("mail.smtp.ssl.socketFactory", sslSocketFactory);
props.put("mail.smtp.ssl.trust", "*");
⚠️ 重要提示: 此方法完全禁用证书验证,仅限测试环境使用。生产环境必须使用受信任 CA 颁发的有效 SSL 证书确保通信安全。
9. 总结
本文演示了使用 Jakarta Mail API 发送邮件的核心功能:
- ✅ 发送纯文本/HTML 邮件
- ✅ 添加附件
- ✅ 格式化邮件内容
- ✅ 发送给多个收件人
- ✅ 配置连接超时
- ✅ 处理开发环境证书问题
通过合理配置 Properties
和组合 MimeBodyPart
,可灵活实现各种邮件发送需求。生产环境中需特别注意证书安全性和超时配置。