发送邮件是常用的业务手法,这里记录使用 Spring 发送邮件和 Hutool 发送.
Spring
首先要启用发件人邮箱的SMTP发邮件服务,这里使用QQ邮箱,QQ邮箱中SMTP密码是单独生成的授权码,需要记录下。
导入依赖
org.springframework.boot
spring-boot-starter-mail
参数配置
spring:
mail:
host: smtp.qq.com # 邮件服务器的SMTP地址
port: 465 # 邮件服务器的SMTP端口
username: [email protected] # 发件人
password: xxxxxxxxxxxxx # 密码,授权码
protocol: smtps # 使用安全协议
properties:
mail.smtp.ssl.enable: true # 使用 qq, gmail邮箱时需强制开启SSL安全连接
参数封装到MailProperties,就是配置邮件的SMTP服务器
发送邮件方法
/**
* @author mafei007
* @date 2020/3/31 22:38
*/
@Component
@Slf4j
public class MailClient {
private final JavaMailSender mailSender;
private final MailProperties mailProperties;
public MailClient(JavaMailSender mailSender, MailProperties mailProperties) {
this.mailSender = mailSender;
this.mailProperties = mailProperties;
}
@Async
public void sendMail(String to, String subject, String content) {
try {
MimeMessage message = mailSender.createMimeMessage();
MimeMessageHelper helper = new MimeMessageHelper(message);
//设置发件人
helper.setFrom(mailProperties.getUsername());
helper.setTo(to);
helper.setSubject(subject);
// 指定内容为 html 文本
helper.setText(content, true);
mailSender.send(helper.getMimeMessage());
} catch (MessagingException e) {
log.error("发送邮件失败:" + e.getMessage(), e);
}
}
}
JavaMailSender 由 SpringBoot 自动配置类生成,详情见MailSenderAutoConfiguration.java。
Thymeleaf模板文件
Title
欢迎你,
存放在 resources/templates/mail/demo.html
发送
@Test
public void testHtmlMail(){
Context context = new Context();
context.setVariable("username", "zhangsan");
// 模板引擎渲染后的 html 文本
String content = templateEngine.process("/mail/demo", context);
mailClient.sendMail("[email protected]", "测试html邮件", content);
}
这里使用了Thymeleaf渲染模板引擎的代码,解释下:
Thymeleaf渲染解读
先说下Thymeleaf中的几个概念:
- Context: 运行上下文
- TemplateResolver:模板解析器
- TemplateEngine:模板引擎
Context
上下文: 用来保存模型数据,就是个 map 存放 key value,当模板引擎渲染时,可以从Context上下文中获取数据用于渲染。
当与SpringBoot结合使用时,我们放入Model的数据就会被处理到Context,作为模板渲染的数据使用。
TemplateResolver
模板解析器:用来读取模板相关的配置,例如:模板存放的位置信息,模板文件名称,模板文件的类型等等。
当与SpringBoot结合时,TemplateResolver已经由其创建完成,并且各种配置也都有默认值,比如模板存放位置,其默认值就是:templates。比如模板文件类型,其默认值就是html。
TemplateEngine
模板引擎:用来解析模板的引擎,需要使用到 Context上下文、TemplateResolver 模板解析器。分别从两者中获取模板中需要的数据,模板文件。然后利用内置的语法规则解析,从而输出解析后的文件。来看下模板引擎进行处理的函数:
templateEngine.process("模板名", context, writer);
三个参数:
- 模板名称
- 上下文:里面包含模型数据
- writer:输出目的地的流
在输出时,我们可以指定输出的目的地,如果目的地是Response的流,那就是网络响应。如果目的地是本地文件,那就实现静态化了。
而在SpringBoot中已经自动配置了模板引擎,可以直接注入使用。
如果不指定输出流:
String content = templateEngine.process("模板名", context);
就可以得到 Thymeleaf 模板渲染后的 html 文本。
使用Hutool发送邮件
sendMail() 方法封装下来跟原生的 javax.mail 邮件操作就没差多少代码,Spring封装的还是非常繁琐,使用 Hutool 就方便多了。
引入依赖
cn.hutool
hutool-extra
5.2.5
javax.mail
mail
1.4.7
邮件服务器配置
在classpath(在标准Maven项目中为src/main/resources)的config目录下新建mail.setting文件.
# 邮件服务器的SMTP地址,可选,默认为smtp.<发件人邮箱后缀>
host = smtp.yeah.net
# 邮件服务器的SMTP端口
port = 465
# 发件人(必须正确,否则发送失败)
from = [email protected]
# 密码(注意,某些邮箱需要为SMTP服务单独设置密码)
pass = q1w2e3
# 使用SSL安全连接
sslEnable = true
#### 以上是建议手动配置的参数#################################################################
#### 下面的参数可以不用配置,默认即可##########################################################
# 用户名(默认提取你邮箱@前面的部分。注意:如果使用foxmail邮箱,此处user为qq号)
user = hutool
#使用 STARTTLS安全连接,STARTTLS是对纯文本通信协议的扩展。
starttlsEnable = true
# 指定实现javax.net.SocketFactory接口的类的名称,这个类将被用于创建SMTP的套接字
socketFactoryClass = javax.net.ssl.SSLSocketFactory
# 如果设置为true,未能创建一个套接字使用指定的套接字工厂类将导致使用java.net.Socket创建的套接字类, 默认值为true
socketFactoryFallback = true
# 指定的端口连接到在使用指定的套接字工厂。如果没有设置,将使用默认端口456
socketFactoryPort = 465
# SMTP超时时长,单位毫秒,缺省值不超时
timeout = 0
# Socket连接超时值,单位毫秒,缺省值不超时
connectionTimeout = 0
发送邮件
- 发送普通文本邮件,最后一个参数可选是否添加多个附件:
MailUtil.send("[email protected]", "测试", "邮件来自Hutool测试", false);
- 发送HTML格式的邮件并附带附件,最后一个参数可选是否添加多个附件:
MailUtil.send("[email protected]", "测试", "邮件来自Hutool测试
", true, FileUtil.file("d:/aaa.xml"));
3.发邮件,可选HTML或普通文本,可选多个附件:
ArrayList tos = CollUtil.newArrayList(
"[email protected]",
"[email protected]",
"[email protected]",
"[email protected]");
MailUtil.send(tos, "测试", "邮件来自Hutool群发测试", false);
发送邮件非常简单,只需一个方法即可搞定其中按照参数顺序说明如下:
- tos: 对方的邮箱地址,可以是单个,也可以是多个(Collection表示)
- subject:标题
- content:邮件正文,可以是文本,也可以是HTML内容
- isHtml: 是否为HTML,如果是,那参数3识别为HTML内容
- files: 可选:附件,可以为多个或没有,将File对象加在最后一个可变参数中即可
@Test
public void testHtmlMailByHutool(){
Context context = new Context();
context.setVariable("username", "zhangsan");
// 模板引擎渲染后的 html 文本
String content = templateEngine.process("/mail/demo", context);
MailUtil.send(mailProperties.getUsername(), "htmlByHutool", content, true);
}
使用 Hutool 工具包就不用我们封装一些发送邮件的代码了,比 Spring 的简单点。
参考
Spring官方文档
Hutool官方文档