网站邮件发送是一个很实用的功能,例如验证码,通知等等。其实使用Spring Boot发送邮件是一件非常简单的事情。
1,配置
首先在项目pom.xml
文件中添加依赖:
<dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-mail</artifactId></dependency>
然后打开Spring Boot配置文件application.properties
,在里面加入邮件配置:
spring.mail.host=邮件的smtp服务器 spring.mail.username=你的邮箱账户 spring.mail.password=邮箱授权码(注意是授权码不是密码) spring.mail.default-encoding=UTF-8
这样就配置好了!
前提是你的邮箱需要开启smtp服务,以163邮箱为例:
开启任意一个即可,然后按照指引操作,最后会得到一个授权码,建议复制到一个文本文档记下来,这个页面也可以看到smtp地址,复制到配置里面即可:
2,发送简单文字邮件
在需要调用邮件发送的类中使用@Autowired
自动注入JavaMailSender
对象,然后创建SimpleMailMessage
实例,进行发送即可,下面给出实例:
"${spring.mail.username}") (privateStringsender; privateJavaMailSendermailSender; publicvoidsendNotifyMail(Stringemail, Stringtitle, Stringtext) { SimpleMailMessagemessage=newSimpleMailMessage(); message.setFrom(sender); message.setTo(email); message.setSubject(title); message.setText(text); try { mailSender.send(message); } catch (Exceptione) { e.printStackTrace(); } }
上面有一个sender
变量使用@Value
注解注入了我们配置的邮箱值,因为发件人邮箱也需要在Java程序中发送邮件时写,方便起见注入配置文件的值即可而不是再写一遍邮箱地址。
以及上面写了个发邮件的方法sendNotifyMail
,这里就是发邮件的方法。可见发邮件只需要先自动注入JavaMailSender
对象,然后创建SimpleMailMessage
实例,并设定SimpleMailMessage
实例的发件人、收件人、邮件标题、邮件内容,最后调用JavaMailSender
实例的send
方法发送SimpleMailMessage
实例即可。
3,发送富文本(HTML)邮件
我们现在见到的很多网站的邮件验证码,都是有一个网页样式的。事实上,我们可以借助JavaMailSender
和Thymeleaf
模板引擎实现富文本邮件发送。
首先记得添加Thymeleaf
依赖:
<dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-thymeleaf</artifactId></dependency>
Thymeleaf
模板文件默认位于项目文件夹/src/main/resources/templates
目录下,我们在这个目录下创建html
的网页模板文件作为邮件模板。Thymeleaf
路径是可以修改的,具体修改方法可以在我的其它一篇博客里面找到。
我这里在默认模板目录下创建一个网页模板miyakomailtemplate.html
如下:
<htmlxmlns:th="http://www.thymeleaf.org"><head><metacharset="utf-8"/><metaname="viewport"content="width=device-width,initial-scale=1.0,minimum-scale=1.0,maximum-scale=1.0,user-scalable=no"><titleth:text="${title}"></title><style> * { margin: 0; padding: 0; } body { background-color: rgb(224, 224, 224); } .background { position: absolute; width: 390px; height: 450px; background-color: white; } .background.head { position: relative; height: 10px; background-color: rgb(0, 153, 255); } .background.content.title, .text { position: relative; margin-top: 3%; margin-left: 5%; width: 90%; } .background.content.title { color: rgb(0, 153, 255); font-weight: 700; font-size: 30px; } .background.content.text { position: relative; padding: 8px; box-sizing: border-box; margin-top: 3%; margin-left: 5%; height: 275px; border: 1.5pxbluesolid; overflow: auto; } .background.content.textp { display: inline; border-bottom: 1pxgreendashed; } .background.miyako { position: absolute; bottom: 14px; right: 5%; display: flex; justify-content: flex-end; align-items: center; width: 300px; } .background.miyako.from { position: relative; margin-right: 16px; font-size: 20px; font-weight: 600; color: rgb(0, 110, 255); } .background.miyakoimg { position: relative; width: 58px; height: 58px; border: 2pxsolidblueviolet; border-radius: 50%; } @media (max-width: 768px) { .background { width: 100%; } } </style></head><body><divclass="background"><divclass="head"></div><divclass="content"><divclass="title"th:text="${title}">标题</div><divclass="text"><pth:text="${content}">内容</p></div></div><divclass="miyako"><divclass="from">From 出云宫子</div><imgsrc="https://s6.jpg.cm/2021/10/27/I07fQS.png"/></div></div></body></html>
这个就是我们的网页邮件模板,可以看到,最上面html
标签加上了xmlns:th="http://www.thymeleaf.org"
表示这是一个Thymeleaf
模板文件,然后在模板中,我们可以设定一些变量,给标签加上th:text=${变量名}
属性,那么在模板引擎读取时就会把该标签内容渲染成相应的值。当然这些变量需要我们后端发送邮件时先指定变量名和值,最后网页就会渲染成相应的样子。
对于富文本邮件网页,我们编写时需要注意:存放我们主体内容的元素(例如我上述中类名为background
的div
元素)不要去设置它的位置(left
,top
)!就保持它在默认位置(一般是在body
中的left
和top
都为0的地方)即可,否则收到的邮件显示会异常。如果不写响应式布局,那么存放我们内容的容器也需要用具体数值来规定其宽高。
当然,我建议还是做一下移动端适配,在网页head
中加上:
<metaname="viewport"content="width=device-width,initial-scale=1.0,minimum-scale=1.0,maximum-scale=1.0,user-scalable=no">
然后使用媒体查询,适配移动端,这样效果会比较好。
媒体查询中存放主体内容的标签就建议把宽度设置为100%
。
变量部分其实就是Thymeleaf
的基本语法,这里不再赘述。
现在,我们来编写后端,封装一个方法发送富文本邮件:
"${spring.mail.username}") (privateStringsender; privateJavaMailSendermailSender; privateTemplateEnginetemplateEngine; // 注入模板引擎读取模板文件publicvoidsendHtmlNotifyMail(Stringemail, Stringtitle, Stringcontent) throwsMessagingException { // 通过Context对象构建模板中变量需要的值Contextcontext=newContext(); context.setVariable("title", title); context.setVariable("content", content); // 传入变量,并渲染模板StringmimeString=templateEngine.process("miyakomailtemplate.html", context); // 创建富文本信息对象MimeMessagemessage=mailSender.createMimeMessage(); MimeMessageHelperhelper=newMimeMessageHelper(message, true); helper.setFrom(sender); helper.setTo(email); helper.setSubject(title); // 给helper设置内容为我们渲染的模板内容,第二个参数为true表示内容是html格式helper.setText(mimeString, true); // 发送邮件try { mailSender.send(message); } catch (Exceptione) { e.printStackTrace(); } }
其实大体思路和上面发送简单文本是很相似的,只不过先创建了个Context
对象,在这个对象里面储存网页模板中的变量名和对应的变量值(setVariable("变量名", "变量值")
,我们上面网页模板中有title
和content
这两个变量,也可见在Java代码中我们在context
这个对象中设定了这两个变量的值),然后使用templateEngine
将模板渲染,传入网页模板位置(相对于Thymeleaf
目录的位置,这里文件直接放在该目录下,因此传入文件名即可)和Context
对象,即可渲染出实际的值。得到网页源代码字符串,发送邮件时将其作为内容发送即可。
我们调用该方法测试一下:
publicvoidtest() { try { sendHtmlNotifyMail("我的邮箱@163.com", "宫子恰布丁-密码重置", "您的密码重置邮箱验证码为:"+ (int) ((Math.random() *9+1) *100000)); } catch (MessagingExceptione) { e.printStackTrace(); } }
效果:
4,将Spring Boot配置到阿里云后无法发送邮件的问题解决
我在本地开发时测试发送邮件正常,但是放到阿里云上面就发不出去了。查资料得知因为邮件默认通过25
端口发送,而出于安全考虑阿里云默认禁用25
端口,因此需要配置加密的465
端口才行。
我们只需要基于上述配置文件内容继续加入下列配置即可:
spring.mail.properties.mail.smtp.socketFactory.class=javax.net.ssl.SSLSocketFactory spring.mail.properties.mail.smtp.socketFactory.port=465 spring.mail.properties.mail.smtp.auth=true spring.mail.properties.mail.smtp.starttls.enable=true spring.mail.properties.mail.smtp.starttls.required=true