SpringBoot实战:手把手教你用Java发送电子邮件(基于 Jakarta Mail)
在现代的 Web 应用开发中,邮件功能几乎是不可或缺的一环。无论是用户注册验证、密码找回、系统通知,还是营销推广,都需要通过邮件与用户建立联系。本文将带你从零开始,使用 Spring Boot 和 Jakarta Mail 实现一个稳定、可配置的邮件发送功能。
我们将基于一个实际的 Spring Boot 项目案例,详细讲解如何集成邮件服务,并提供完整的代码示例和配置说明。
前期准备:
在邮箱设置中开启SMTP服务并获取授权码
📦 1. 项目依赖:引入 Jakarta Mail
首先,在 pom.xml
中添加邮件支持的依赖。从 Java EE 迁移到 Jakarta EE 后,推荐使用 jakarta.mail
替代旧的 javax.mail
。
<dependency>
<groupId>com.sun.mail</groupId>
<artifactId>jakarta.mail</artifactId>
<version>2.0.1</version>
</dependency>
✅ 提示:
jakarta.mail
是javax.mail
的继任者,适用于 Jakarta EE 9+ 和 Spring Boot 3+ 环境。
🛠️ 2. 邮件配置:使用 application.yml
为了实现配置与代码分离,我们将邮件服务器的相关信息写入 application.yml
:
mail:
host: smtp.qiye.163.com # 邮箱服务器地址(SMTP)
port: 587 # SMTP 端口(启用 STARTTLS)
username: hash@ithash.cn # 发件人邮箱账号
password: xxxxxxxxxxxx # 客户端授权码(非登录密码!)
⚠️ 安全提醒:
password
应填写邮箱的 客户端授权码,而不是登录密码。以网易企业邮箱为例,需在邮箱设置中开启“客户端授权密码”功能并生成专用密钥。
常用邮箱的SMTP服务器地址和端口信息汇总表:
📌 重要提示:
授权码 vs 登录密码
对于QQ、网易系列(163/126/企业邮)等国内邮箱,不能直接使用登录密码进行SMTP验证。必须在邮箱设置中开启“SMTP服务”,并生成一个客户端授权码用于程序登录。TLS 与 SSL 端口区别
端口 587 + STARTTLS/TLS:明文连接后升级为加密(推荐)
端口 465 / 994 + SSL:直接建立SSL加密连接(传统方式)
安全性建议
优先使用 TLS(端口587)或 SSL(如465/994)进行加密传输。
不要将密码或授权码硬编码在代码中,应使用配置文件或环境变量管理。
🧩 3. 配置类:封装邮件参数
我们创建一个配置类 EmailSenderPropertis
,用于自动绑定 application.yml
中的配置项。
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.stereotype.Component;
import lombok.Data;
@Data
@Component
@ConfigurationProperties(prefix = "mail")
public class EmailSenderPropertis {
private String host;
private String port;
private String username;
private String password;
}
@ConfigurationProperties(prefix = "mail")
:将mail.*
配置自动映射到该类字段。@Data
:Lombok 注解,自动生成 getter/setter、toString 等方法。@Component
:注册为 Spring 容器的 Bean。
📨 4. 邮件发送核心类:EmailSender
这是整个功能的核心,负责构建邮件并发送。
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import jakarta.mail.*;
import jakarta.mail.internet.InternetAddress;
import jakarta.mail.internet.MimeMessage;
import java.util.Properties;
@Component
public class EmailSender {
@Autowired
private EmailSenderPropertis emailSenderPropertis;
/**
* 发送简单文本邮件
* @param to 接收方邮箱
* @param subject 邮件主题
* @param body 邮件正文
*/
public void send(String to, String subject, String body) {
String host = emailSenderPropertis.getHost();
String port = emailSenderPropertis.getPort();
String username = emailSenderPropertis.getUsername();
String password = emailSenderPropertis.getPassword();
// 1. 设置邮件服务器属性
Properties props = new Properties();
props.put("mail.smtp.host", host);
props.put("mail.smtp.port", port);
props.put("mail.smtp.auth", "true");
props.put("mail.smtp.starttls.enable", "true"); // 启用 TLS 加密
// 2. 创建身份认证器
Authenticator auth = new Authenticator() {
protected PasswordAuthentication getPasswordAuthentication() {
return new PasswordAuthentication(username, password);
}
};
// 3. 获取邮件会话
Session session = Session.getInstance(props, auth);
try {
// 4. 构建邮件内容
Message message = new MimeMessage(session);
message.setFrom(new InternetAddress(username)); // 发件人
message.setRecipients(Message.RecipientType.TO, InternetAddress.parse(to)); // 收件人
message.setSubject(subject); // 主题
message.setText(body); // 正文(纯文本)
// 5. 发送邮件
Transport.send(message);
System.out.println("✅ 邮件发送成功!");
} catch (MessagingException e) {
e.printStackTrace();
System.err.println("❌ 发送邮件失败: " + e.getMessage());
}
}
}
🔍 关键点解析:
✅ 5. 测试验证:使用 JUnit 单元测试
编写测试类验证邮件是否能正常发送。
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
@SpringBootTest
public class EmailTest {
@Autowired
private EmailSender emailSender;
@Test
public void testSend() {
emailSender.send("x@ithash.cn", "测试邮件", "这是一封测试邮件");
}
}
注意在测试类上使用 @SpringBootTest
注解。该注解用于启动完整的 Spring 应用上下文,以便在测试中能够正确地注入和使用 Spring Bean(如 EmailSender
)以及加载Sping配置文件。这将确保你的单元测试能够在与实际应用相同的环境中运行,从而提高测试的准确性和可靠性。
运行测试后,如果控制台输出 ✅ 邮件发送成功!
,并且收件箱收到邮件,则说明集成成功。
🛡️ 6. 常见问题与解决方案
❌ 发送失败:Could not connect to SMTP host
检查
host
和port
是否正确。确保网络可访问该 SMTP 服务器(可能被防火墙拦截)。
企业邮箱可能需要开启 SMTP 服务。
❌ 认证失败:Authentication failed
注意网易邮箱和网易企业邮箱的SMTP服务器地址不同。
确认
password
是 授权码 而非登录密码。检查用户名是否完整(包含域名,如
xxx@ithash.cn
)。
❌ TLS/SSL 问题
若使用端口 465,应使用
mail.smtp.ssl.enable=true
并关闭starttls
。端口 587 通常配合
STARTTLS
使用(本文配置)。
🚀 7. 扩展功能建议
发送 HTML 网页邮件
使用message.setContent(body, "text/html;charset=UTF-8")
替代setText()
。添加附件
使用MimeMultipart
构建多部分消息。异步发送
使用@Async
注解提升系统响应速度。模板引擎集成
结合 Thymeleaf 或 FreeMarker 生成动态邮件内容。日志与监控
记录发送状态,集成邮件发送成功率监控。
📚 8. 总结
本文通过一个完整的 Spring Boot 示例,演示了如何使用 Jakarta Mail 实现邮件发送功能。我们实现了:
配置与代码解耦
安全的授权码机制
可复用的邮件发送组件
单元测试验证
这套方案简洁、稳定,适用于大多数企业级应用。你可以在此基础上扩展更复杂的邮件功能,如批量发送、定时任务、失败重试等。