这篇内容对应"2.1 发送邮件"小节
对应视频:9-发送邮件
视频链接
邮箱设置
需要去邮箱对应的官方客户端软件或网站开启IMAP/SMTP服务或POP3/SMTP服务器
如果不开启,就无法使用第三方用户代理,只能走第官方的电子邮件客户端软件或网站,用户代理就是电子邮件客户端软件。
开启之后,我们就可以用Spring Email技术将整合的JavaMailSender作为发送邮件的用户代理。
Spring Email
导入Jar包
要想使用邮件Spring整合的邮件功能,需要导入spring boot start mail Jar包
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-mail</artifactId>
<version>2.1.5.RELEASE</version>
</dependency>
邮箱参数配置
不要将邮箱相关参数写死在Java程序中,而是应该写作配置文件中,方便以后修改。
邮箱相关参数:
- host:电子邮件服务器域名,Spring Email用户代理需要向那个服务器发送邮件
- port:端口,20 世纪 90 年代,一些电子邮件服务提供商已开始使用 SMTPS,当时使用的是 安全套接字层协议 (SSL),这是 TLS 的原始版本,现已弃用。他们为此指定了端口 465,尽管没有任何官方互联网机构批准使用该端口。
- protocol:用户代理向电子邮件服务器发送邮件所使用的协议,注意smtp与smtps不一样
- username:邮件发送发的邮箱
- password:邮件发送方的密码 因为SMTP协议认证要求必须提供账户名和密码才能登录服务器,其设计目的在于避免用户受到垃圾邮件的侵扰。
- properties.mail.smtp.ssl.enable: 是否启用安全连接
配置文件如下:
spring:
mail:
host: smtp.sina.com
port: 465
properties:
mail:
smtp:
ssl:
enable: true
protocol: smtps
username: nowcoder@sina.com
password: nowcoder123
使用JavaMailSender发送邮件
JavaMailSender是一个接口类,我们通过其实现类JavaMailSenderImpl来进行邮件的发送,发送邮件的逻辑最好封装一下,这样可以反复的使用,复用代码。
所以,新建一个包,包名叫util,专门用于存放工具类
然后,在util报下新建一个MailClient类,邮箱客户端,因为JavaMailSender在发送邮件的过程中,扮演的角色是用户代理(电子邮件客户端软件)
所以将这个类取名为MaillClient。
一封邮件邮件的格式:
JavaMailSender接口源码:
public interface JavaMailSender extends MailSender {
MimeMessage createMimeMessage();
MimeMessage createMimeMessage(InputStream var1) throws MailException;
void send(MimeMessage var1) throws MailException;
void send(MimeMessage... var1) throws MailException;
void send(MimeMessagePreparator var1) throws MailException;
void send(MimeMessagePreparator... var1) throws MailException;
}
可以发现JavaMailSender 接口就两类方法
send方法从字面既可以理解,这是用于发邮件的。
createMimeMessage 方法是干什么的呢?
要想理解这个方法,主要是要理解中间Mime的含义,Mime全称是Multipurpose Internet Mail Extension,多用途因特网邮件拓展。
那这个MIME有什么用呢?前面我们在配置时,使用的邮件传输协议时smtps,该协议与smtp一样,都支持传输ASCCII码文本数据,不可以传输其他可执行文件或者二进制对象,甚至连中文文字都传输不了。
SMTP无法满足传送多媒体邮件(带有图片、音频或视频数据)的需要,并且许多非英语国家的文字也无法使用通过SMTP传输。所以,为了解决SMTP无法传输非ASCII码文本的问题,MIME(Multipurpose Internet Mail Extension,多用途因特网邮件拓展)应运而生了。MIME最主要的作用就是定义了传送编码,可对任意内容格式进行转换,而不会被邮件系统所改变。
MailClient 类源码:
package com.nowcoder.community.util;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.mail.javamail.JavaMailSender;
import org.springframework.mail.javamail.MimeMessageHelper;
import org.springframework.stereotype.Component;
import javax.mail.MessagingException;
import javax.mail.internet.MimeMessage;
/*
* 表示说我这个bean需要有spring容器来管理,
* 而且使用@Component注解表示说是一个比较通用的bean,
* 在哪些层次都可以使用。
* */
@Component
public class MailClient {
private static final Logger logger = LoggerFactory.getLogger(MailClient.class);
/*
* 要使用的核心组件是JavaMailSender,这个注解已经由spring来管理了
* 我们直接注入即可获取JavaMailSenderImpl实现类对象
* */
@Autowired
private JavaMailSender mailSender;
/*
* 发送邮件需要几个条件:
* 1、邮件发送方(由于是服务器发送邮件,所以这个是固定的)
* 2、邮件接收方
* 3、邮件主题
* 4、邮件内容
* */
@Value("${spring.mail.username}")
private String from;
public void sendMail(String to, String subject, String content) {
try {
MimeMessage message = mailSender.createMimeMessage();
/*
* 这里通过message也可以实现setFrom,setTo等。
* 但是MimeMessageHelper帮助我们进行一些基础功能的实现比如:
* 邮箱地址检查是否满足格式、字符串是不是为空等等
* */
MimeMessageHelper helper = new MimeMessageHelper(message);
helper.setFrom(from);
helper.setTo(to);
helper.setSubject(subject);
/*
* 表示运行支持html文本,将html转成字符传进来它也支持
* */
helper.setText(content, true);
mailSender.send(helper.getMimeMessage());
} catch (MessagingException e) {
logger.error("发送邮件失败:" + e.getMessage());
}
}
}
/*
* 表示运行支持html文本,将html转成字符传进来它也支持
* */
helper.setText(content, true);
这里为什么要将传入true,因为我们要把html转成字符串设置从content,让MIME去解析。如果不设置为true,它就会当作不同字符串。
模板引擎
为什么要用模板引擎?
- 我们要发送HTML邮件(不用模板引擎也可以做到),HTML是静态页面。更美观的页面
- HTML里面有动态生成的激活码(根本原因)更丰富的信息
测试HTML页面发送
在templates/mail目录下,新建demo.html模板。demo.html内容如下:
<!DOCTYPE html>
<html lang="en" xmlns:th="http://www.thymeleaf.org">
<head>
<meta charset="UTF-8">
<title>邮件示例</title>
</head>
<body>
<p>欢迎你, <span style="color:red;" th:text="${username}"></span>!</p>
</body>
</html>
如何生成模板渲染后端html页面?
如果是在Spring MVC的情况下,非常简单。 在controller中,某个方法,直接return 模板的路径名称,让后Spring MVC会自动找到改模板,并将Model中的数据渲染到视图中。
如果不是在Spring MVC的情况下,需要程序员手动去调用代码实现这个过程。主动的去调用Thymeleaf模板引擎:
- 注入thymeleaf模板引擎对象,TemplateEngine
- 利用thymeleaf的上下文对象 Context,设置username的值
- 调用模板引擎TemplateEngine对象,将数据渲染到html,生成动态网页TemplateEngine中有一个process方法,传入视图的路径名称,和上下文对象。
如图所示,相当于我们是直接从红色部分区域开始的。
建立MailTests类,代码如下:
package com.nowcoder.community;
import com.nowcoder.community.util.MailClient;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.junit4.SpringRunner;
import org.thymeleaf.TemplateEngine;
import org.thymeleaf.context.Context;
@RunWith(SpringRunner.class)
@SpringBootTest
@ContextConfiguration(classes = CommunityApplication.class)
public class MailTests {
@Autowired
private MailClient mailClient;
@Autowired
private TemplateEngine templateEngine;
@Test
public void testTextMail() {
mailClient.sendMail("lihonghe@nowcoder.com", "TEST", "Welcome.");
}
@Test
public void testHtmlMail() {
Context context = new Context();
context.setVariable("username", "sunday");
String content = templateEngine.process("/mail/demo", context);
System.out.println(content);
mailClient.sendMail("lihonghe@nowcoder.com", "HTML", content);
}
}