上一篇
用 JavaMail 库,引入依赖后配置 SMTP 服务器信息,创建Session对象,构建MimeMessage设置收发件人及内容
以下是使用 Java 实现邮件功能的详细指南,涵盖核心原理、完整代码示例、关键配置解析及常见问题解决方案:
技术选型与前置条件
主流方案对比表
| 方案 | 特点 | 适用场景 |
|---|---|---|
javax.mail (现 Jakarta Mail) |
标准 S/MIME 协议支持,兼容主流邮箱服务商 | 企业级应用开发 |
| Spring Boot Starter Mail | 基于 Spring Boot 自动装配,简化模板引擎集成 | 快速开发 Web 应用 |
| Apache Commons Email | 轻量级封装,适合简单需求 | 小型项目/脚本任务 |
| 云服务商 SDK (如阿里云) | 免运维,提供 API 接口 | 高并发/大规模发送场景 |
推荐方案:Jakarta Mail(原 JavaMail)+ SMTP 协议,因其灵活性高且无需额外框架依赖。
环境准备清单
- JDK 版本:≥8(推荐 LTS 版本如 17)
- 依赖引入(Maven):
<dependency> <groupId>com.sun.mail</groupId> <artifactId>jakarta.mail</artifactId> <version>2.0.1</version> </dependency> - SMTP 服务账号:需提前申请并开启 SMTP 服务(如 Gmail 需允许低安全性应用访问)。
核心实现步骤详解
️ 1. 配置 SMTP 会话参数
通过 Properties 对象定义邮件服务器连接参数,关键属性如下表:
| 属性名 | 示例值 | 说明 |
|---|---|---|
mail.smtp.host |
smtp.gmail.com | SMTP 服务器地址 |
mail.smtp.port |
587 | TLS 默认端口(HTTPS 为 465) |
mail.smtp.auth |
true | 启用身份验证 |
mail.smtp.starttls.enable |
true | 启用 TLS 加密(重要!防止明文传输) |
mail.smtp.ssl.trust |
信任所有证书(生产环境建议替换为具体 CA 证书) |
️ 2. 创建邮件会话与消息体
// 1. 创建会话对象(携带身份验证器)
Session session = Session.getInstance(props, new Authenticator() {
@Override
protected PasswordAuthentication getPasswordAuthentication() {
return new PasswordAuthentication("your_email@example.com", "your_password");
}
});
// 2. 构建 MIME 消息
Message message = new MimeMessage(session);
message.setFrom(new InternetAddress("sender@example.com")); // 发件人
message.setRecipients(Message.RecipientType.TO, InternetAddress.parse("receiver@example.com")); // 收件人
message.setSubject("测试邮件主题"); // 主题
message.setText("这是纯文本邮件内容"); // 正文(支持 HTML)
3. 发送邮件的核心逻辑
try {
Transport.send(message); // 同步发送(阻塞直至完成)
System.out.println("邮件发送成功!");
} catch (MessagingException e) {
e.printStackTrace(); // 捕获异常(如认证失败、网络中断等)
}
进阶功能扩展
1. 发送 HTML 格式邮件
String htmlContent = "<h1 style='color:red;'>红色标题</h1><p>带样式的段落</p>"; message.setContent(htmlContent, "text/html;charset=UTF-8"); // 设置内容类型为 HTML
️ 注意:若同时包含文本和 HTML 版本,需使用 Multipart 组合两种格式。
2. 添加附件(支持多文件)
// 创建多部分容器
Multipart multipart = new MimeMultipart();
// 添加文本部分
BodyPart textPart = new MimeBodyPart();
textPart.setText("请查看附件");
multipart.addBodyPart(textPart);
// 添加附件(示例:PDF 文件)
File file = new File("path/to/file.pdf");
MimeBodyPart attachmentPart = new MimeBodyPart();
attachmentPart.attachFile(file); // 自动设置 Content-Disposition
multipart.addBodyPart(attachmentPart);
// 设置整个消息内容为多部分
message.setContent(multipart);
3. SSL/TLS 安全连接优化
- 显式 SSL(端口 465):将
mail.smtp.port改为 465,并移除starttls.enable。 - 隐式 TLS(端口 587):保持默认配置,现代邮件服务器优先推荐此方式。
- 证书校验:生产环境应禁用
mail.smtp.ssl.trust,改为加载可信 CA 证书链。
异常处理与调试技巧
常见错误及解决方案表
| 错误现象 | 可能原因 | 解决方案 |
|---|---|---|
Authentication failed |
账号/密码错误或未开启 SMTP | 检查账号权限,确认密码正确性 |
Connection timed out |
网络不通或防火墙拦截 | 检查端口开放性,尝试代理服务器 |
Could not connect to host |
DNS 解析失败或服务器地址错误 | 验证 mail.smtp.host 是否正确 |
Invalid content type |
MIME 类型不匹配 | 确保附件文件类型与实际一致 |
Quota exceeded |
邮箱存储空间不足 | 清理收件箱或升级账户容量 |
调试建议
- 启用日志输出:在
Session创建时添加session.setDebug(true);,可打印详细交互过程。 - 使用 Wireshark:抓包分析 SMTP 协议交互细节。
- 测试工具替代:先用 Thunderbird 等客户端测试账号能否正常收发邮件。
完整代码示例(含注释)
import jakarta.mail.;
import jakarta.mail.internet.;
import java.util.Properties;
public class EmailSender {
public static void main(String[] args) {
// 1. 配置 SMTP 服务器参数
Properties props = new Properties();
props.put("mail.smtp.host", "smtp.gmail.com");
props.put("mail.smtp.port", "587");
props.put("mail.smtp.auth", "true");
props.put("mail.smtp.starttls.enable", "true");
props.put("mail.smtp.ssl.trust", ""); // 仅测试环境使用!
// 2. 创建会话并设置身份验证
Session session = Session.getInstance(props, new Authenticator() {
@Override
protected PasswordAuthentication getPasswordAuthentication() {
return new PasswordAuthentication("your_email@gmail.com", "your_app_specific_password");
}
});
session.setDebug(true); // 启用调试日志
try {
// 3. 创建 MIME 消息
Message message = new MimeMessage(session);
message.setFrom(new InternetAddress("your_email@gmail.com")); // 发件人
message.setRecipients(Message.RecipientType.TO, InternetAddress.parse("receiver@example.com")); // 收件人
message.setSubject("Java 邮件测试 带附件"); // 主题
// 4. 构造多部分内容(文本+附件)
Multipart multipart = new MimeMultipart();
// 文本部分
MimeBodyPart textPart = new MimeBodyPart();
textPart.setText("您好!请查收附件中的文档。", "utf-8");
multipart.addBodyPart(textPart);
// 附件部分(示例:Word 文档)
MimeBodyPart attachmentPart = new MimeBodyPart();
attachmentPart.attachFile(new File("C:/test/document.docx"));
multipart.addBodyPart(attachmentPart);
// 5. 设置消息内容并发送
message.setContent(multipart);
Transport.send(message);
System.out.println("邮件发送成功!");
} catch (Exception e) {
e.printStackTrace();
}
}
}
FAQs(常见问题解答)
Q1: 为什么会出现 “Authentication failed” 错误?
A: 主要原因包括:① 使用了错误的账号/密码组合;② 未开启 SMTP 服务(如 Gmail 需在账户设置中启用);③ 使用了双因素认证但未生成专用应用密码,解决方法:检查账号权限,确认密码正确性,必要时生成并使用应用专用密码。
Q2: 如何给多个收件人发送邮件?
A: 使用 message.setRecipients() 方法传入多个 InternetAddress 对象即可,示例:
Address[] toAddresses = new Address[] {
new InternetAddress("user1@example.com"),
new InternetAddress("user2@example.com")
};
message.setRecipients(Message.RecipientType.TO, toAddresses);
若需区分抄送(CC)或密送(BCC),可分别使用 Message.RecipientType.CC 和 Message.RecipientType.BCC
