1. 概述
本教程将带你一步步实现在普通 Spring 应用和 Spring Boot 应用中发送邮件。前者使用 JavaMail 库,后者则依赖 spring-boot-starter-mail
依赖。
2. Maven 依赖
首先需要在 pom.xml
中添加依赖。
2.1. Spring 框架
普通 Spring 项目需添加以下依赖:
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context-support</artifactId>
<version>6.1.5</version>
</dependency>
最新版本可在 Maven 仓库 查询。
2.2. Spring Boot
Spring Boot 项目添加:
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-mail</artifactId>
<version>3.1.5</version>
</dependency>
最新版本见 Maven Central。
3. 邮件服务器配置
Spring 框架的邮件支持接口和类组织如下:
MailSender
接口:顶层接口,提供基础邮件发送功能JavaMailSender
接口:MailSender
的子接口,支持 MIME 消息,常与MimeMessageHelper
配合使用JavaMailSenderImpl
类:JavaMailSender
的实现类,支持MimeMessage
和SimpleMailMessage
SimpleMailMessage
类:用于创建简单邮件(包含发件人、收件人、抄送、主题和正文)MimeMessagePreparator
接口:MIME 消息准备的回调接口MimeMessageHelper
类:创建 MIME 消息的辅助类,支持图片、附件和 HTML 内容
3.1. Spring 邮件配置
通过 JavaMailSenderImpl
指定 SMTP 服务器等属性。Gmail 配置示例:
@Bean
public JavaMailSender getJavaMailSender() {
JavaMailSenderImpl mailSender = new JavaMailSenderImpl();
mailSender.setHost("smtp.gmail.com");
mailSender.setPort(587);
mailSender.setUsername("[email protected]");
mailSender.setPassword("your-app-password");
Properties props = mailSender.getJavaMailProperties();
props.put("mail.transport.protocol", "smtp");
props.put("mail.smtp.auth", "true");
props.put("mail.smtp.starttls.enable", "true");
props.put("mail.debug", "true");
return mailSender;
}
3.2. Spring Boot 邮件配置
在 application.properties
中使用 spring.mail.*
命名空间配置:
spring.mail.host=smtp.gmail.com
spring.mail.port=587
spring.mail.username=[email protected]
spring.mail.password=your-app-password
spring.mail.properties.mail.smtp.auth=true
spring.mail.properties.mail.smtp.starttls.enable=true
⚠️ 某些 SMTP 服务器需要 TLS 连接,通过 spring.mail.properties.mail.smtp.starttls.enable
启用。
3.2.1. Gmail SMTP 配置
通过 Gmail SMTP 发送邮件时需注意:
- 密码需使用 Google 账户生成的 应用专用密码
- 参考 Gmail 官方文档 获取服务器属性
3.2.2. Amazon SES SMTP 配置
使用 Amazon SES 时配置如下:
spring.mail.host=email-smtp.us-west-2.amazonaws.com
spring.mail.username=your-ses-username
spring.mail.password=your-ses-password
spring.mail.properties.mail.transport.protocol=smtp
spring.mail.properties.mail.smtp.port=25
spring.mail.properties.mail.smtp.auth=true
spring.mail.properties.mail.smtp.starttls.enable=true
spring.mail.properties.mail.smtp.starttls.required=true
⚠️ Amazon 要求先验证凭证,参考 官方指南。
4. 发送邮件
配置完成后,使用 JavaMailSender
发送邮件。普通 Spring 和 Spring Boot 的发送方式相同。
4.1. 发送简单邮件
无附件的简单邮件发送示例:
@Component
public class EmailServiceImpl implements EmailService {
@Autowired
private JavaMailSender emailSender;
public void sendSimpleMessage(
String to, String subject, String text) {
SimpleMailMessage message = new SimpleMailMessage();
message.setFrom("[email protected]");
message.setTo(to);
message.setSubject(subject);
message.setText(text);
emailSender.send(message);
}
}
✅ 虽然发件人地址非必填,但多数 SMTP 服务器会拒绝无发件人的邮件。
4.2. 发送带附件邮件
需要发送附件时(如订单确认邮件的发票),使用 MimeMessageHelper
:
@Override
public void sendMessageWithAttachment(
String to, String subject, String text, String pathToAttachment) {
MimeMessage message = emailSender.createMimeMessage();
MimeMessageHelper helper = new MimeMessageHelper(message, true);
helper.setFrom("[email protected]");
helper.setTo(to);
helper.setSubject(subject);
helper.setText(text);
FileSystemResource file
= new FileSystemResource(new File(pathToAttachment));
helper.addAttachment("Invoice", file);
emailSender.send(message);
}
4.3. 邮件模板
SimpleMailMessage
支持字符串格式化,可定义模板 Bean:
@Bean
public SimpleMailMessage templateSimpleMessage() {
SimpleMailMessage message = new SimpleMailMessage();
message.setText(
"这是您的邮件测试模板:\n%s\n");
return message;
}
使用模板时只需传入参数:
@Autowired
private SimpleMailMessage template;
// ...
String text = String.format(template.getText(), templateArgs);
sendSimpleMessage(to, subject, text);
5. 处理发送错误
JavaMail
提供 SendFailedException
处理发送失败,但实际使用中可能遇到以下问题:
- 异常不会抛出:RFC 821 规定 SMTP 服务器遇到无效地址应返回 550 错误码,但多数公共服务器(如 Gmail)不会抛出异常,而是发送“投递失败”邮件或无反馈
- 可选方案:
- 捕获
SendFailedException
(但可能永远不会触发) - 定期检查发件箱的“投递失败”通知(实现复杂且时间不确定)
- 若服务器无反馈则无法处理
- 捕获
6. 总结
本文介绍了在 Spring Boot 应用中配置和发送邮件的方法。所有示例代码可在 GitHub 获取。