赞
踩
一、邮件基础说明
我们经常会听到各种各样的邮件协议,比如 SMTP、POP3,那么这些协议有什么作用,有什么区别呢?
SMTP协议说明
SMTP 协议全称为 Simple Mail Transfer Protocol,译作简单邮件传输协议,它定义了邮件客户端软件与SMTP服务器之间,以及SMTP服务器与SMTP服务器之间的通信规则。它是一个基于TCP/IP的应用层协议,江湖地位有点类似于HTTP,SMTP服务器默认监听的端口号为25。
POP3协议说明
POP3协议全称为 Post Office Protocol ,译作邮局协议,它定义了邮件客户端与POP3服务器之间的通信规则。
那么该协议在什么场景下会用到呢?举例说明
当邮件到达网易的SMTP服务器之后, xxx@163.com 用户需要登录服务器查看邮件,这个时候就该协议就用上了:邮件服务商都会为每一个用户提供专门的邮件存储空间,SMTP服务器收到邮件之后,就将邮件保存到相应用户的邮件存储空间中,如果用户要读取邮件,就需要通过邮件服务商的POP3邮件服务器来完成。
二、准备工作
在账户选项卡中找到开启POP3/SMTP选项,点击开启,开启相关功能,开启过程需要手机号码验证,按照步骤操作即可,不赘述开启。成功之后,即可获取一个授权码,将该号码保存好,后面代码中要使用。
导入pom依赖
在创建的工程中,导入相关的依赖。
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.2.1.RELEASE</version>
<relativePath/>
</parent>
<groupId>com.swk</groupId>
<artifactId>email-springboot</artifactId>
<version>0.0.1-SNAPSHOT</version>
<name>email-springboot</name>
<description>Demo project for Spring Boot</description>
<properties>
<java.version>8</java.version>
</properties>
<dependencies>
<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>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
</plugins>
</build>
</project>
配置邮箱信息
在工程的yml或者properties文件中,配置邮箱相关信息。
server.port=8080
# 配置smtp服务器地址
spring.mail.host=smtp.qq.com
# 配置smtp服务器的端口
spring.mail.port=587
# 配置邮箱用户名
spring.mail.username=写你自己的邮箱
# 配置密码
spring.mail.password=gimthtwpgclabdje
# 配置默认编码
spring.mail.default-encoding=UTF-8
# 配置ssl加密工厂
spring.mail.properties.mail.smtp.socketFactoryClass=javax.net.ssl.SSLSocketFactory
# 配置开启 DEBUG 模式
spring.mail.properties.mail.debug=true
完成配置后,SpringBoot会自动帮我们配置好邮件发送类。相关源码配置如下:
@Configuration(proxyBeanMethods = false)
@ConditionalOnClass({ MimeMessage.class, MimeType.class, MailSender.class })
@ConditionalOnMissingBean(MailSender.class)
@Conditional(MailSenderCondition.class)
@EnableConfigurationProperties(MailProperties.class)
@Import({ MailSenderJndiConfiguration.class, MailSenderPropertiesConfiguration.class })
public class MailSenderAutoConfiguration {
static class MailSenderCondition extends AnyNestedCondition {
MailSenderCondition() {
super(ConfigurationPhase.PARSE_CONFIGURATION);
}
@ConditionalOnProperty(prefix = "spring.mail", name = "host")
static class HostProperty {
}
@ConditionalOnProperty(prefix = "spring.mail", name = "jndi-name")
static class JndiNameProperty {
}
}
}
从上述代码中,可以看到,导入了另一个配置MailSenderPropertiesConfiguration 类,这个类中提供了邮件发送相关的工具类,源码如下:
@Configuration(proxyBeanMethods = false)
@ConditionalOnClass(Session.class)
@ConditionalOnProperty(prefix = "spring.mail", name = "jndi-name")
@ConditionalOnJndi
class MailSenderJndiConfiguration {
// 有参构造
private final MailProperties properties;
MailSenderJndiConfiguration(MailProperties properties) {
this.properties = properties;
}
// 邮件发送组件
@Bean
JavaMailSenderImpl mailSender(Session session) {
JavaMailSenderImpl sender = new JavaMailSenderImpl();
sender.setDefaultEncoding(this.properties.getDefaultEncoding().name());
sender.setSession(session);
return sender;
}
@Bean
@ConditionalOnMissingBean
Session session() {
String jndiName = this.properties.getJndiName();
try {
return JndiLocatorDelegate.createDefaultResourceRefLocator().lookup(jndiName, Session.class);
}
catch (NamingException ex) {
throw new IllegalStateException(String.format("Unable to find Session in JNDI location %s", jndiName), ex);
}
}
}
可以看到,这里创建了一个JavaMailSenderImpl的实例,JavaMailSenderImpl是JavaMailSender的一个实现,我们将使用JavaMailSenderImpl来完成邮件的发送工作。
三 、发送邮件测试
发送简单邮件
简单邮件就是指邮件内容是一个普通的文本文档。
/**
* 1 发送简单邮件
* 简单邮件就是指邮件内容是一个普通的文本文档
*/
@Test
public void sendSimpleMail(){
//1 构建邮件接收对象
SimpleMailMessage simpleMailMessage = new SimpleMailMessage();
//2 设置邮件主题
simpleMailMessage.setSubject("这是一封测试邮件");
//3 设置邮件发送者
simpleMailMessage.setFrom("写自己的邮箱,比如qq邮箱");
//4 设置邮件接收者(可以设置多个接收者)
simpleMailMessage.setTo("写自己的邮箱,比如qq邮箱");
//5 设置邮件抄送人,可以有多个抄送人
simpleMailMessage.setCc("写自己的邮箱,比如qq邮箱");
//6 设置隐秘抄送人,可以有多个
simpleMailMessage.setBcc("写自己的邮箱,比如qq邮箱");
//7 设置邮件发送日期
simpleMailMessage.setSentDate(new Date());
//8 设置邮件的正文
simpleMailMessage.setText("这是测试邮件的正文");
//9 发送邮件
javaMailSender.send(simpleMailMessage);
}
运行程序之后,查看邮箱:
发送带附件的邮件
邮件的附件可以是图片,也可以是普通文件,都是支持的。
/**
* 2 发送带附件的邮件
*
*/
@Test
public void sendAttachFileMail() throws MessagingException {
//1 构建复杂邮件对象
MimeMessage mimeMessage = javaMailSender.createMimeMessage();
// MimeMessageHelper 邮件信息配置的辅助类
MimeMessageHelper helper = new MimeMessageHelper(mimeMessage,true);
//2 设置邮件主题
helper.setSubject("这是一封测试邮件");
//3 设置邮件发送者
helper.setFrom("写自己的邮箱,比如qq邮箱");
//4 设置邮件接收者(可以设置多个接收者)
helper.setTo("写自己的邮箱,比如qq邮箱");
//5 设置邮件抄送人,可以有多个抄送人
helper.setCc("写自己的邮箱,比如qq邮箱");
//6 设置隐秘抄送人,可以有多个
helper.setBcc("写自己的邮箱,比如qq邮箱");
helper.setSentDate(new Date());
helper.setText("这是测试邮件的正文");
//7 添加附件
helper.addAttachment("1680510755381.jpg",new File("C:\\Users\\Administrator\\Pictures\\Saved Pictures\\1680510755381.jpg"));
javaMailSender.send(mimeMessage);
}
运行程序之后,查看邮箱:
发送带图片资源的邮件
图片资源和附件有什么区别呢?
图片资源是放在邮件正文中的,即一打开邮件,就能看到图片。但是一般来说,不建议使用这种方式,一些公司会对邮件内容的大小有限制(因为这种方式是将图片一起发送的)。
/**
* 3 发送带图片资源的邮件
*
*/
@Test
public void sendImgResMail() throws MessagingException {
//1 构建复杂邮件对象
MimeMessage mimeMessage =javaMailSender.createMimeMessage();
// MimeMessageHelper 邮件信息配置的辅助类
MimeMessageHelper helper = new MimeMessageHelper(mimeMessage, true);
//2 设置邮件主题
helper.setSubject("这是一封测试邮件");
//3 设置邮件发送者
helper.setFrom("写自己的邮箱,比如qq邮箱");
//4 设置邮件接收者(可以设置多个接收者)
helper.setTo("写自己的邮箱,比如qq邮箱");
//5 设置邮件抄送人,可以有多个抄送人
helper.setCc("写自己的邮箱,比如qq邮箱");
//6 设置隐秘抄送人,可以有多个
helper.setBcc("写自己的邮箱,比如qq邮箱");
helper.setSentDate(new Date());
//7 setText方法参数一表示:是一个 HTML 文本,里边涉及到的图片资源先用一个占位符占着
// 参数二表示:设置为true,表示第一个参数是一个 HTML 文本
helper.setText("<p>hello 大家好,这是一封测试邮件,这封邮件包含两种图片,分别如下</p><p>第一张图片:</p><img src='cid:p01'/><p>第二张图片:</p><img src='cid:p02'/>",true);
//8 设置图片资源
helper.addInline("p01",new FileSystemResource(new File("C:\\Users\\Administrator\\Pictures\\Saved Pictures\\1680510755381.jpg")));
helper.addInline("p02",new FileSystemResource(new File("C:\\Users\\Administrator\\Pictures\\Saved Pictures\\1680510755381.jpg")));
javaMailSender.send(mimeMessage);
}
运行程序后,查看邮箱:
在实际开发中,第一种和第三种都不是使用最多的邮件发送方案。因为正常来说,邮件的内容都是比较的丰富的,所以大部分邮件都是通过HTML来呈现的,如果直接拼接 HTML字符串,这样以后不好维护,为了解决这个问题,一般邮件发送,都会有相应的邮件模板。最具代表性的两个模板就是Freemarker模板和Thyemeleaf模板了。
测试Freemarker模板发送邮件
在pom文件中引入freemarker依赖:
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-freemarker</artifactId>
</dependency>
在项目的resources/templates目录下创建一个email.ftl文件,作为邮件发送模板:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>
<p>hello 欢迎加入 邮件测试 大家庭,您的入职信息如下:</p>
<table border="1">
<tr>
<td>姓名</td>
<td>${username}</td>
</tr>
<tr>
<td>工号</td>
<td>${num}</td>
</tr>
<tr>
<td>薪水</td>
<td>${salary}</td>
</tr>
</table>
<div style="color: #ff1a0e">一起努力,创造辉煌</div>
</body>
</html>
编写User实体类:
public class User {
private String username;
private Integer num;
private Double salary;
public User() {
}
public User(String username, Integer num, Double salary) {
this.username = username;
this.num = num;
this.salary = salary;
}
public String getUsername() {
return username;
}
public void setUsername(String username) {
this.username = username;
}
public Integer getNum() {
return num;
}
public void setNum(Integer num) {
this.num = num;
}
public Double getSalary() {
return salary;
}
public void setSalary(Double salary) {
this.salary = salary;
}
@Override
public String toString() {
return "User{" +
"username='" + username + '\'' +
", num=" + num +
", salary=" + salary +
'}';
}
}
编写测试类,将邮件模板渲染成为HTML,然后发送。
/**
* 4 基于freemarker发送邮件
*
*/
@Test
public void sendFreemarkerMail() throws MessagingException,
IOException, TemplateException {
MimeMessage mimeMessage =
javaMailSender.createMimeMessage();
MimeMessageHelper helper = new
MimeMessageHelper(mimeMessage, true);
helper.setSubject("这是一封测试邮件");
helper.setFrom("写自己的邮箱,比如qq邮箱");
helper.setTo("写自己的邮箱,比如qq邮箱");
helper.setCc("写自己的邮箱,比如qq邮箱");
helper.setBcc("写自己的邮箱,比如qq邮箱");
helper.setSentDate(new Date());
//构建 Freemarker 的基本配置
Configuration configuration = new
Configuration(Configuration.VERSION_2_3_0);
// 配置模板位置
ClassLoader loader = EmailSpringbootApplicationTests.class.getClassLoader();
configuration.setClassLoaderForTemplateLoading(loader,
"templates");
//加载模板
Template template = configuration.getTemplate("email.ftl");
User user = new User();
user.setUsername("swk");
user.setNum(1);
user.setSalary((double) 99999);
StringWriter out = new StringWriter();
//模板渲染,渲染的结果将被保存到 out 中 ,将out中的html字符串发送即可
template.process(user, out);
helper.setText(out.toString(),true);
javaMailSender.send(mimeMessage);
}
运行程序后,查看邮箱:
测试Thymleaf模板发送邮件
推荐在SpringBoot中使用Thymeleaf来构建邮件模板。因为Thymeleaf的自动化配置提供了一个TemplateEngine ,通过TemplateEngine可以方便的将Thymeleaf模板渲染为HTML ,同时,Thymeleaf的自动化配置在这里是继续有效的。
在pom中引入Thymleaf依赖
<!DOCTYPE html>
<html lang="en" xmlns:th="http://www.thymeleaf.org">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>
<p>hello 欢迎加入 xxx 大家庭,您的入职信息如下:</p>
<table border="1">
<tr>
<td>姓名</td>
<td th:text="${username}"></td>
</tr>
<tr>
<td>工号</td>
<td th:text="${num}"></td>
</tr>
<tr>
<td>薪水</td>
<td th:text="${salary}"></td>
</tr>
</table>
<div style="color: #ff1a0e">一起努力,创造辉煌</div>
</body>
</html>
编写测试类,并发送邮件。
@Autowired
private TemplateEngine templateEngine;
/**
* 5 基于thymleaf发送邮件
*
*/
@Test
public void sendThymeleafMail() throws MessagingException {
MimeMessage mimeMessage =
javaMailSender.createMimeMessage();
MimeMessageHelper helper = new
MimeMessageHelper(mimeMessage, true);
helper.setSubject("这是一封测试邮件");
helper.setFrom("写自己的邮箱,比如qq邮箱");
helper.setTo("写自己的邮箱,比如qq邮箱");
helper.setCc("写自己的邮箱,比如qq邮箱");
helper.setBcc("写自己的邮箱,比如qq邮箱");
helper.setSentDate(new Date());
// 使用thymleaf上下文对象设置对象信息
Context context = new Context();
context.setVariable("username", "swk");
context.setVariable("num","000001");
context.setVariable("salary", "8888");
// 指定写出的模板
String process = templateEngine.process("email.html", context);
helper.setText(process,true);
javaMailSender.send(mimeMessage);
}
运行程序后,查看邮箱:
总结
上述就是使用SpringBoot发送邮件的5种方式,针对发送内容可以分为简单文本邮件、带附件邮件、带图片资源邮件、整合FreeMarker发送邮件、整合ThymLeaf发送邮件。在实际开发中使用SpringBoot默认整合的ThymLeaf模板完成,也可以根据需要进行自定义配置。
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。