Spring Email(邮件)发送指南
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>
最新版本可在 此处 获取。
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 中央仓库 获取。
3、邮件服务器配置属性
Spring 框架中邮件支持的接口与类按以下结构组织:
MailSender
接口:顶层接口,提供发送简单邮件的基础功能。JavaMailSender
接口:MailSender
的子接口,支持 MIME 消息,通常与。MimeMessageHelper
类配合创建MimeMessage
。建议通过MimeMessagePreparator
机制使用该接口。JavaMailSenderImpl
类:实现JavaMailSender
接口,支持MimeMessage
和SimpleMailMessage
。SimpleMailMessage
类:用于创建包含发件人、收件人、抄送、主题和文本内容的简单邮件。MimeMessagePreparator
接口:为 MIME 消息提供准备机制的回调接口。MimeMessageHelper
类:创建 MIME 消息的辅助类,支持图片、典型邮件附件及 HTML 格式的文本内容。
以下章节将演示如何使用这些接口与类。
3.1、Spring 邮件服务器配置属性
指定 SMTP 服务器等必需的邮件属性可通过 JavaMailSenderImpl
进行定义。
以 Gmail 为例,配置如下:
@Bean
public JavaMailSender getJavaMailSender() {
JavaMailSenderImpl mailSender = new JavaMailSenderImpl();
mailSender.setHost("smtp.gmail.com");
mailSender.setPort(587);
mailSender.setUsername("my.gmail@gmail.com");
mailSender.setPassword("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.*
命名空间配置邮件服务器属性。
Gmail SMTP 服务器的配置示例如下:
spring.mail.host=smtp.gmail.com
spring.mail.port=587
spring.mail.username=<login user to smtp server>
spring.mail.password=<login password to smtp server>
spring.mail.properties.mail.smtp.auth=true
spring.mail.properties.mail.smtp.starttls.enable=true
部分 SMTP 服务器要求 TLS 加密连接,此时需通过 spring.mail.properties.mail.smtp.starttls.enable
属性启用 TLS 保护。
3.2.1、Gmail SMTP 配置属性
可通过 Gmail SMTP 服务器发送邮件,具体出站邮件服务器属性请参阅 文档。
我们的 application.properties
文件已配置为使用 Gmail SMTP(参见前文配置)。
注意:账户密码需使用为 Google 账户生成的专用应用密码,而非普通密码。详情及密码生成方法请参考 此链接。
3.2.2、SES SMTP 配置属性
使用 Amazon SES 发送邮件时,需按以下方式配置 application.properties
:
spring.mail.host=email-smtp.us-west-2.amazonaws.com
spring.mail.username=username
spring.mail.password=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("noreply@baeldung.com");
message.setTo(to);
message.setSubject(subject);
message.setText(text);
emailSender.send(message);
...
}
}
需注意:虽然 from
地址非必填项,但多数 SMTP 服务器会拒收此类邮件。因此我们在 EmailService
实现中使用了 noreply@baeldung.com
作为发件地址。
4.2、发送带有附件的邮件
有时 Spring 的简单邮件功能无法满足需求。
例如发送带发票附件订单确认邮件时,需使用 JavaMail 库的 MIME Multipart 消息而非 SimpleMailMessage
。
Spring 通过 org.springframework.mail.javamail.MimeMessageHelper
类支持 JavaMail 消息处理。
首先在 EmailServiceImpl
中添加发送附件邮件的方法:
@Override
public void sendMessageWithAttachment(
String to, String subject, String text, String pathToAttachment) {
// ...
MimeMessage message = emailSender.createMimeMessage();
MimeMessageHelper helper = new MimeMessageHelper(message, true);
helper.setFrom("noreply@baeldung.com");
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(
"This is the test email template for your email:\n%s\n");
return message;
}
现在可将此 Bean 作为邮件模板使用,只需向模板提供必要参数:
@Autowired
public SimpleMailMessage template;
...
String text = String.format(template.getText(), templateArgs);
sendSimpleMessage(to, subject, text);
4.4、通过 InputStream 发送邮件附件
当需要发送动态生成或通过 InputStream
获取的附件时,可利用 Spring 框架的 MimeMessageHelper
类实现。
以下是在 EmailServiceImpl
类中添加通过 InputStream
发送附件的方法:
public void sendMessageWithInputStreamAttachment(
String to, String subject, String text, String attachmentName, InputStream attachmentStream) {
try {
MimeMessage message = emailSender.createMimeMessage();
MimeMessageHelper helper = new MimeMessageHelper(message, true);
helper.setFrom("noreply@baeldung.com");
helper.setTo(to);
helper.setSubject(subject);
helper.setText(text);
// 从 InputStream 添加附件
helper.addAttachment(attachmentName, new InputStreamResource(attachmentStream));
emailSender.send(message);
} catch (MessagingException e) {
e.printStackTrace();
}
}
该方法首先通过 JavaMailSender
创建 MimeMessage
实例,随后初始化 MimeMessageHelper
以支持包含附件所需的 Multipart 消息结构。
调用 addAttachment()
时,使用 InputStreamResource
封装传入的 InputStream
,从而支持附加非文件形式的动态数据。
现在可调用此方法:
InputStream attachmentStream = new ByteArrayInputStream("Hello World".getBytes(StandardCharsets.UTF_8));
emailService.sendMessageWithInputStreamAttachment(
"recipient@example.com",
"Subject Here",
"Body of the email",
"attachment.txt",
attachmentStream);
本示例将字符串转换为 InputStream
后作为名为 "attachment.txt"
的附件发送。此方法无需预先将内容保存为磁盘文件,即可灵活发送各类附件。
5、处理发送异常
JavaMail 提供 SendFailedException
处理邮件发送失败的情况,但发送至错误地址时可能不会触发此异常。原因如下:
RFC 821 的 SMTP 协议规范要求服务器在发送至错误地址时返回 550 状态码,但多数公共 SMTP 服务器并未遵守 - 它们可能发送 “delivery failed”(投递失败)回执邮件或完全不提供反馈。
例如,Gmail SMTP 服务器会发送 “delivery failed” 回执邮件,但程序不会抛出异常。
针对此情况,可以有以下处理方案:
- 捕获可能永远不会抛出的
SendFailedException
。 - 在限定时间内检查发件箱中的 “delivery failed” 回执(此方式不直观且时间周期不确定)。
- 若邮件服务器无任何反馈,则没任何办法了。
6、总结
本文介绍了如何在 Spring 和 Spring Boot 应用中发送邮件。
Ref:https://www.baeldung.com/spring-email