SMTP是一种提供可靠且有效的电子邮件传输的协议,SMTP是建立在FTP文件传输服务上的一种邮件服务,主要用于系统之间的邮件信息传递,并提供有关来信的通知。
邮件发送功能相信很多小伙伴都有接触过,这也是实际开发中最常见的需求,比如用户注册,找回密码,下订单等等,这里小编就不一一阐述了,接下来小编带你一步步实现它,由于Spring Boot更新迭代速度贼快,我们就来使用目前官方正式发布的最新版本2.3.2对邮件发送进行实战。
SpringBoot发送QQ邮件必须先打开QQ邮箱的SMTP功能,默认是关闭的,打开SMTP功能,就能获取申请授权码,这里我给大家演示我们本次项目的QQ邮箱获取授权码的方式。
1、首先登录QQ邮箱PC版,点击上方的设置按钮
2、切换到账户选项卡中
3、找到开启POP3/IMAP/SMTP/Exchange/CardDAV/CalDAV服务的选项
将第一个开启,这里我已经开启了,就不用再开启了,点击POP3/SMTP开启相关功能服务,开启过程中需要手机号验证,根据步骤执行即可。开启成功后会获得一个授权码,保存好即可,后面编码会用到。
快速创建Spring Boot项目,引入邮件发送的依赖支持,在Spring Boot中自动配置了邮件相关功能,对于开发者来说只需要引入相关依赖就可以了,无配置集成,这就是Spring Boot强大的地方。
pom.xml依赖如下:
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-mail</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
项目创建成功,此时我们需要在application.yml中配置邮箱信息,如果小伙伴们喜欢properties方式配置文件,后面文章末尾也会给大家提供,我个人推荐yml的语法配置方式,看你心情吧。
server:
port: 8081
spring:
mail:
host: smtp.qq.com
port: 587
username: [email protected]
password: xxxxxx
default-encoding: UTF-8
properties:
mail:
smtp:
socketFactoryClass: javax.net.ssl.SSLSocketFactory
debug: true
这里小编给大家一个表,解释一下每个配置参数的意思,当然还有很多配置列表,我这里列了主要配置信息:
配置 | 含义 |
---|---|
host | SMTP服务器地址 |
port | SMTP服务器端口 |
username | 邮箱账号带上后缀 |
password | 申请的授权码 |
default-encoding | 默认邮件编码 |
socketFactoryClass | 开启ssl加密,保证安全连接 |
debug | 开启DEBUG模式,打印邮件发送过程日志,方便排除错误 |
为了测试方便,我们在Spring Boot提供的测试包中给大家直接演示简单的邮件发送,首先我们先看一张图,可能很多小伙伴不常发送邮箱,我们看看实际操作是怎么发送邮箱的。
看图说话,小伙伴会想到什么呢?收件人、抄送人、密送人、主题、正文(多种文本格式,以及文件) 有这么多选项?NB,那我们就用编写一个测试类代码实操一波吧。
@SpringBootTest
class EmailApplicationTests {
@Autowired
private JavaMailSender javaMailSender;
@Test
public void sendEmail() {
// new一个邮件对象
SimpleMailMessage mailMessage = new SimpleMailMessage();
// 设置主题
mailMessage.setSubject("测试邮件");
// 设置发送人
mailMessage.setFrom("[email protected]");
// 设置接收人,可以有多个
mailMessage.setTo("[email protected]");
// 设置抄送人,可以有多个
mailMessage.setCc("[email protected]");
// 设置隐秘抄送人,可以有多个
mailMessage.setBcc("[email protected]");
// 设置发送日期
mailMessage.setSentDate(new Date());
// 设置邮件正文
mailMessage.setText("您的验证码为8081");
// 调用邮件发送接口方法
javaMailSender.send(mailMessage);
}
}
Spring提供了非常好用的JavaMailSender接口实现邮件发送,在Spring Boot中也提供了相应的自动化配置,大大简化开发无配置集成,一个字‘爽’。
我们看看效果:
Nice,这就成功发送邮件了,So easy,I’m blind? 不,你没瞎,就是如此简单,Spring Boot这波集成,666,这样我们就实现了一个简单的邮件发送功能。
心累,又到了装B环节,粗俗,是时候展示真正的技术了:打开org.springframework.boot.autoconfigure.mail这个类,邮件相关配置都在这里面
找到mail包点击进去:
我们会发现该类里面导入了这样一个配置(MailSenderPropertiesConfiguration.class):
再点击该配置类进去,揭开神秘面纱:
可以发现该类给我们提供了邮件发送功能的相关bean容器,刚刚通过 @Autowired注入该bean实现了简单的邮件功能,是不是很熟悉啊。
@Autowired
private JavaMailSender javaMailSender;
一层一层剥开你的心,继续我们点击进入JavaMailSender.class:
可以发现JavaMailSender.class它是一个接口,并且继承了MailSender接口,是的MailSender还是一个接口,我们残忍的再次点击进去了解一下
这就是接口的继承(类是单继承,接口是多继承哦),接口继承是为了在不修改接口的情况下,扩展接口的功能,提高代码的重用率,减低耦合性,可以和面试官吹NB了,不枉费我一层层揭开它的真面目,原来确实是个美女,哈哈哈。
刚刚我们只是单纯的测试字符串文本的邮件发送,来点高级货,ok,安排上,我们来写写带附件的邮件(图片或者office文档)。
@Test
public void sendEmailFile() throws MessagingException {
// 获取复杂的邮件对象
MimeMessage mailMessage = javaMailSender.createMimeMessage();
// 邮件配置辅助工具类
MimeMessageHelper helper = new MimeMessageHelper(mailMessage,true);
helper.setSubject("测试邮件带附件发送");
helper.setFrom("[email protected]");
helper.setTo("[email protected]");
helper.setCc("[email protected]");
helper.setBcc("[email protected]");
helper.setSentDate(new Date());
helper.setText("您的验证码为8082");
// 设置附件
helper.addAttachment("1.jpg",new File("D://imgtest//1.jpg"));
// 调用邮件发送接口方法
javaMailSender.send(mailMessage);
}
通过addAttachment方法,即可放入我们的附件,如此必须看一波源码啊,原谅我手贱,实在忍不住,难得不会,简单的我们还是看得懂的,哈哈。
测试效果:
此时的邮件对象不是普通发送的SimpleMailMessage,而是通过javaMailSender.createMimeMessage()获取复杂的邮件对象,然后再利用MimeMessageHelper对邮件进行辅助配置,实现邮件带附件的发送功能,这里是通过addAttachment方法来添加附件,我们可以看看源码:
File file 看到没,这不就是创建一个新 File 实例嘛,在内存中创建File文件映射对象,通过addAttachment添加附件。MimeMessageHelper类中addAttachment方法源码,给了明确的使用解释,第一个参数为文件名称,第二个参数为源文件,并且文件不能为null。
说明:org.springframework.mail.javamail.MimeMessageHelper是处理JavaMail邮件时比较顺手组件之一,它可以让你摆脱繁复的JavaMail API。
4、发送带图片类资源的邮件:
图片类资源和附件的区别就是:图片类资源是在邮件正文中,打开就能看到。
@Test
public void sendEmailResFile() throws MessagingException {
// 获取复杂的邮件对象
MimeMessage mailMessage = javaMailSender.createMimeMessage();
// 邮件配置辅助工具类
MimeMessageHelper helper = new MimeMessageHelper(mailMessage,true);
helper.setSubject("测试邮件带附件发送");
helper.setFrom("[email protected]");
helper.setTo("[email protected]");
helper.setCc("[email protected]");
helper.setBcc("[email protected]");
helper.setSentDate(new Date());
helper.setText("测试邮件,包含两种图片,分别如下:
第一张图片:
第二张图片:
",true);
// 设置图片类资源
helper.addInline("it1",new FileSystemResource(new File("D://imgtest//it01.jpg")));
helper.addInline("it2",new FileSystemResource(new File("D://imgtest//it02.jpg")));
// 调用邮件发送接口方法
javaMailSender.send(mailMessage);
}
测试效果:
这里是通过setText设置附件类型,我们可以看看该方法的源码:
其中text参数是一个HTML文本,第二个参数,是个boolean类型,参数名称为html,我们可以知道当他为true的时候,会给我们解析成html,相信小伙伴们都使用过富文本编辑器,通过存储html,设置不同的标签,就可以把内容渲染成一个网页,显示不同的标题、字体样式等。
我们要发送邮件的时候,是不是一个一个拼接HTML字符串呢?
NO,NO,NO,太麻烦了,而且容易写错,能粘贴绝对不写(哈哈),那么我们再来一种实在的方式,使用邮件模板进行发送邮箱,那么我们文章开头引入thymeleaf模板就可以派上用场了,前方高能,看我如何扭转乾坤 … … …
首先得引入thymeleaf模板引擎依赖,thymeleaf用过吧!不管我事(呵呵),废话不多说,再贴一遍:
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-thymeleaf</artifactId>
</dependency>
创建thymeleaf邮件模板:
<html lang="en" xmlns:th="http://www.thymeleaf.org">
<head>
<meta charset="UTF-8">
<title>Titletitle>
head>
<body>
<div style="font-size: 25px;text-align: center;color: #000;font-weight: bold;">
<span>入职通知书span>
div>
<div style="text-align: center;padding: 10px;">
<img th:src="${avatar}"/>
div>
<div style="color: #0060f1;text-decoration: underline;">
<span th:text="${username}">span>
div>
<p style="padding: 20px;">您好,很高兴通知您,通过对您两轮面试表现的综合评估,恭喜您已成功被我司录取!p>
<div style="margin: 20px;">您的职位是:
<span style="color: blue;text-decoration: underline;" th:text="${position}">span>
div>
<p style="color: #0e0d0e">欢迎您加入我们的团队,希望大家一起努力,实现梦想~p>
<a style="color: blue;" th:text="公司地址+':'+${link}" th:href="${link}">a>
body>
html>
Thymeleaf提供了TemplateEngine来对模板进行渲染,通过Context构造模板中变量需要的值,具体代码如下:
@Test
public void sendEmailTemplate() throws MessagingException {
// 获取复杂的邮件对象
MimeMessage mailMessage = javaMailSender.createMimeMessage();
// 邮件配置辅助工具类
MimeMessageHelper helper = new MimeMessageHelper(mailMessage,true);
helper.setSubject("thymeleaf邮件发送");
helper.setFrom("[email protected]");
helper.setTo("[email protected]");
helper.setCc("[email protected]");
helper.setBcc("[email protected]");
helper.setSentDate(new Date());
// 利用 Thymeleaf 模板构建 html 文本
Context context = new Context();
context.setVariable("username","DT小白");
context.setVariable("position","Java开发工程师");
context.setVariable("avatar","http://ydfblog.cn/build/img/ydflogo4-f9dc927993e6e370c62e92b331fd5fc3.jpeg");
context.setVariable("link","http://ydfblog.cn");
// 指定模板路径
String emailText = templateEngine.process("email.html",context);
helper.setText(emailText ,true);
// 调用邮件发送接口方法
javaMailSender.send(mailMessage);
}
1、context.setVariable(),第一个参数是String,第二个是Object类型。第一个参数就对应thymeleaf模板上面相同名字的参数。
2、templateEngine.process()将指定路径的html文件转换成String类型返回。
测试效果:
干货差不多了,这里附上所有代码的gitee码云地址,有需要的自取:
https://gitee.com/summerydf/emailitems.git
如果你觉得DT_小白文章写的还不错,请微信搜索并关注「 Java云社 」微信公众号,和DT_小白一起学习Java、分布式、微服务、大数据技术,并且「 Java云社 」收集了大量的大厂面试题目集,等你来挖掘,为了提升自己的能力,实现技术能力的飞跃,每天定时更新超硬核技术干货,我在「 Java云社 」等您的加入,让我们共同学习吧!