Spring Email
基础知识
什么是SMTP? SMTP全称为Simple Mail Transfer Protocol(简单邮件传输协议),它是一组用于从源地址到目的地址传输邮件的规范,通过它来控制邮件的中转方式。SMTP认证要求必须提供账号和密码才能登陆服务器,其设计目的在于避免用户受到垃圾邮件的侵扰。
什么是IMAP? IMAP全称为Internet Message Access Protocol(互联网邮件访问协议),IMAP允许从邮件服务器上获取邮件的信息、下载邮件等。IMAP与POP类似,都是一种邮件获取协议。
什么是POP3? POP3全称为Post Office Protocol 3(邮局协议),POP3支持客户端远程管理服务器端的邮件。POP3常用于“离线”邮件处理,即允许客户端下载服务器邮件,然后服务器上的邮件将会被删除。目前很多POP3的邮件服务器只提供下载邮件功能,服务器本身并不删除邮件,这种属于改进版的POP3协议。
IMAP和POP3协议有什么不同呢? 两者最大的区别在于,IMAP允许双向通信,即在客户端的操作会反馈到服务器上,例如在客户端收取邮件、标记已读等操作,服务器会跟着同步这些操作。而对于POP协议虽然也允许客户端下载服务器邮件,但是在客户端的操作并不会同步到服务器上面的,例如在客户端收取或标记已读邮件,服务器不会同步这些操作。
JavaMailSender和JavaMailSenderImpl
什么是
JavaMailSender
和JavaMailSenderImpl
?JavaMailSender
和JavaMailSenderImpl
是Spring官方提供的集成邮件服务的接口和实现类,以简单高效的设计著称,目前是Java
后端发送邮件和集成邮件服务的主流工具。如何通过
JavaMailSenderImpl
发送邮件? 非常简单,直接在业务类注入JavaMailSenderImpl
并调用send
方法发送邮件。其中简单邮件可以通过SimpleMailMessage
来发送邮件,而复杂的邮件(例如添加附件)可以借助MimeMessageHelper
来构建MimeMessage
发送邮件。例如:
准备工作
引入spring-boot-starter-mail
依赖:
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-mail</artifactId>
</dependency>
在application.yml
文件中指定邮件服务器属性:
spring:
mail:
protocol: smtp
host: smtp.qq.com
port: xxx
username: xxx@qq.com
password: xxx
properties:
mail:
smtp:
auth: true # 开启SMTP身份认证
timeout: 5000 # 连接超时时间
write-timeout: 5000 # 写入超时时间
starttls:
enable: true # 开启TLS加密
发送电子邮件
构建一份普通的电子邮件,并发送给zhangsan@qq.com
@Autowired
private JavaMailSender mailSender;
public void sendMessage() {
SimpleMailMessage message = new SimpleMailMessage();
message.setFrom("coder@qq.com"); // 发件人
message.setTo("zhangsan@qq.com"); // 收件人
message.setSubject("验证码"); // 邮件主题
message.setText("你的验证码:123456"); // 邮件正文
mailSender.send(message);
}
注意
通过setFrom()
方法提供发件人地址并不是强制的,但是许多 SMTP 服务器会拒绝没有提供发件人的消息。这就是我们使用setForm
提供发件人电子邮件地址的原因。
向多人发送电子邮件
message.setTo("zhangsan@qq.com", "lisi@qq.com");
发送HTML电子邮件
要在Spring Boot中发送 HTML 电子邮件,就像发送普通电子邮件一样,必须使用JavaMailSender
接口代替SimpleMailMessage
,使用MimeMessage
,它允许你用setContent
方法将邮件的内容设置为HTML内容:
@Autowired
private JavaMailSender mailSender;
public void sendMessage() throws MessagingException {
MimeMessage message = mailSender.createMimeMessage();
String htmlContent = "<h1>This is a test Spring Boot email</h1> <p>邮件发送功能测试</p>";
message.setFrom("coderlzw@qq.com");
message.setRecipients(MimeMessage.RecipientType.TO, "coder_lzw@163.com");
message.setSubject("Boot Test");
message.setContent(htmlContent, "text/html;charset=UTF-8");
mailSender.send(message);
}
另一种更常用的方法是使用 HMTL 模板发送电子邮件。根据特定的用例,可以将模板保存为单独的HTML文件,与Java
代码的类路径或单独的数据库保存在同一个目录中。
要在电子邮件中使用 HTML 模板,可以创建一个字符串变量,其中包含模板的内容,然后使用该变量设置电子邮件的内容:
@Autowired
private JavaMailSender mailSender;
public void sendEmailFromTemplate() throws MessagingException {
MimeMessage message = mailSender.createMimeMessage();
message.setFrom(new InternetAddress("coder@qq.com"));
message.setRecipients(MimeMessage.RecipientType.TO, "zhangsan@qq.com");
message.setSubject("Boot Test");
// 将HTML模板读入一个字符串变量
String htmlTemplate = readFile("template.html");
// 用动态值替换HTML模板中的占位符
htmlTemplate = htmlTemplate.replace("${name}", "John Doe");
htmlTemplate = htmlTemplate.replace("${message}", "Hello, this is a test email.");
message.setContent(htmlTemplate, "text/html; charset=utf-8");
mailSender.send(message);
}
向多人发送电子邮件
@Autowired
private JavaMailSender mailSender;
@GetMapping
public void sendMessage() throws MessagingException {
MimeMessage message = mailSender.createMimeMessage();
String htmlContent = "<h1>This is a test Spring Boot email</h1> <p>邮件发送功能测试</p>";
message.setFrom("coderlzw@qq.com");
Address[] addresses = {
new InternetAddress("lisi@qq.com"),
new InternetAddress("zhangsan@qq.com")
};
message.setRecipients(MimeMessage.RecipientType.TO, addresses);
message.setSubject("邮件标题");
message.setContent(htmlContent, "text/html;charset=UTF-8");
mailSender.send(message);
}
带附件的电子邮件
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));
emailSender.send(message);
处理发送错误
JavaMail
提供了SendFailedException
来处理无法发送消息的情况。但当我们向错误的地址发送电子邮件时,我们可能不会遇到此异常。原因如下:
RFC 821 中的 SMTP 协议规范指定 SMTP 服务器在尝试将电子邮件发送到不正确的地址时应返回的 550 返回代码。但大多数公共 SMTP 服务器不这样做。相反,他们会发送“交付失败”电子邮件或根本不提供任何反馈。
最后更新于
这有帮助吗?