Spring Boot 发送邮件
第一部分 背景
邮件使用场景
- 注册验证
- 网站营销
- 安全的最后一道防线
- 提醒、监控告警
- 触发机制
邮件发送原理
- 邮件传输协议:SMTP协议和POP3协议
- 内容不断发展:IMAP协议和Mime协议
邮件发送历史
- 1969年10月,世界上的第一封电子邮件
- 987年9月14日,中国的第一封电子邮件
- 30多年的发展历程
- Java发送邮件
- Spring发送邮件
Spring Boot 介绍
- 约定大于配置
- 简单快速开发
- 强大的生态链
- Spring Boot和发送邮件
前置知识
- 会使用Spring进行开发
- 对Spring Boot有一定了解
- Maven\HTML\Thymeleaf
- 理解邮件发送的基础知识
第二部分 实践
- 发送文本邮件
- 发送HTML邮件
- 发送附件邮件
- 发送带图片的邮件
- 邮件模板
- 邮件系统
项目配置信息
-
在
https://start.spring.io/
下载spring boot初始化项目 -
使用maven的方式配置依赖包的引入
<dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-mail</artifactId> </dependency>
-
需要在配置文件中配置一下发送邮件的基本信息,使用的配置文件为:
application.properties
,配置信息如下:spring.mail.host=smtp.sina.com spring.mail.username=XXX@sina.com spring.mail.password=****** spring.mail.default-encoding=utf-8
发送文本邮件
-
创建一个名为MailService的服务类
- 主要功能为发送邮件
- 注入JavaMailSender类用于发送邮件
- 书写一个方法sendSimpleMail用于发送邮件,并设置相关的参数
代码示例如下:
@Service public class MailService { @Value("${spring.mail.username}") private String from; @Autowired private JavaMailSender mailSender; public void sendSimpleMail(String to,String subject,String content){ SimpleMailMessage message=new SimpleMailMessage(); message.setTo(to); message.setSubject(subject); message.setText(content); message.setFrom(from); mailSender.send(message); } }
-
创建一个测试类MailServiceTest,用于测试发送邮件
代码示例如下:
@RunWith(SpringRunner.class) @SpringBootTest public class MailServiceTest { @Resource MailService mailService; @Test public void sendSimpleMail(){ mailService.sendSimpleMail("XXX@qq.com","这是一封测试邮件","内容为文本格式"); } }
-
运行测试方法,如通过则正确
注意事项
- 在使用邮箱发送之前需要到对应的邮箱设置里面开启smtp服务
- QQ邮箱作为发送邮箱,需要设置授权码
发送HTML邮件
同上,分别创建一个服务类和一个测试类
服务类代码如下:
注:helper.setText(content,true);
的参数中有两个,true需要指定是否是html格式
@Service
public class MailService {
@Value("${spring.mail.username}")
private String from;
@Autowired
private JavaMailSender mailSender;
public void sendHtmlMail(String to,String subject,String content) throws MessagingException {
MimeMessage message=mailSender.createMimeMessage();
MimeMessageHelper helper=new MimeMessageHelper(message,true);
helper.setTo(to);
helper.setSubject(subject);
helper.setText(content,true);
helper.setFrom(from);
mailSender.send(message);
}
}
测试类代码如下:
public class MailServiceTest {
@Resource
MailService mailService;
@Test
public void sendHtmlMail() throws MessagingException {
String content="<h3>hello world,这是html邮件内容</h3>";
mailService.sendHtmlMail("XXX@qq.com","这是一封html邮件",content);
}
}
发送附件邮件
服务类代码如下:
如有多个附件,可以将filePath
参数设置为数组类型,然后在方法中进行遍历设置
@Service
public class MailService {
@Value("${spring.mail.username}")
private String from;
@Autowired
private JavaMailSender mailSender;
public void sendAttachmentsMail(String to,String subject,String content,String filePath) throws MessagingException {
MimeMessage message=mailSender.createMimeMessage();
MimeMessageHelper helper=new MimeMessageHelper(message,true);
helper.setTo(to);
helper.setSubject(subject);
helper.setText(content,true);
helper.setFrom(from);
FileSystemResource file=new FileSystemResource(new File(filePath));
String fileName=file.getFilename();
helper.addAttachment(fileName,file);
mailSender.send(message);
}
}
测试类代码如下:
@RunWith(SpringRunner.class)
@SpringBootTest
public class MailServiceTest {
@Resource
MailService mailService;
@Test
public void sendAttachmentsMail() throws MessagingException {
String content="<h3>hello world,这是附件邮件内容</h3>";
String filePath="C:\\unknow.log";
mailService.sendAttachmentsMail("XXX@qq.com","这是一封附件邮件",content,filePath);
}
}
发送带图片的邮件
服务类代码如下:
@Service
public class MailService {
@Value("${spring.mail.username}")
private String from;
@Autowired
private JavaMailSender mailSender;
public void sendInlinResourceMail(String to, String subject, String content, String rscPath, String contentId) throws MessagingException {
MimeMessage message = mailSender.createMimeMessage();
MimeMessageHelper helper = new MimeMessageHelper(message, true);
helper.setTo(to);
helper.setSubject(subject);
helper.setText(content, true);
helper.setFrom(from);
FileSystemResource res = new FileSystemResource(new File(rscPath));
helper.addInline(contentId, res);
mailSender.send(message);
}
}
测试类代码如下:
@RunWith(SpringRunner.class)
@SpringBootTest
public class MailServiceTest {
@Resource
MailService mailService;
@Test
public void sendInlinResourceMail() throws MessagingException {
String imgPath = "C:\\images.JPG";
String contentId = "img001";
String content = "<h3>hello world,这是图片邮件内容<img src='cid:" + rscId + "'></img></h3>";
mailService.sendInlinResourceMail("XXX@qq.com", "这是一封图片邮件", content, imgPath, contentId);
}
}
注:
在邮件中添加图片时,需要指定contentId,然后拼接到正文html中
模板邮件
添加maven依赖,使用thymeleaf模板引擎
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-thymeleaf</artifactId>
</dependency>
添加html模板文件,路径:\src\main\resources\templates\emailTemplate.html
模板文件代码如下:
<!DOCTYPE html>
<html lang="en" xmlns:th="http://www.thymeleaf.org">
<head>
<meta charset="UTF-8">
<title>邮件模板</title>
</head>
<body>
你好,这是一封测试邮件,请点击下面的链接进行验证
<a href="#" th:href="@{http://www.baidu.com/{id}(id=${id})}">点击验证</a>
</body>
</html>
注:
- 添加声明:xmlns:th=“http://www.thymeleaf.org”
- thymeleaf模板引擎的标签都是由th:XXX开头
- 了解模板引擎中的占位符及一些相关规则
书写测试代码,代码如下:
@RunWith(SpringRunner.class)
@SpringBootTest
public class MailServiceTest {
@Resource
MailService mailService;
@Resource
TemplateEngine templateEngine;
@Test
public void MailTemplate() throws MessagingException {
Context context=new Context();
context.setVariable("id","10086");
String emailContext=templateEngine.process("emailTemplate",context);
mailService.sendHtmlMail("XXX@qq.com","这是一封模板邮件",emailContext);
}
}
注:
- 注入模板引擎类:TemplateEngine
org.thymeleaf.TemplateEngine
- 使用Context类对象进行传参
org.thymeleaf.context.Context
- 最终发送的邮件是html格式的邮件
异常处理及常见错误
在服务类中添加日志类代码,记录日志信息,以发送html格式邮件为例
代码如下:
@Service
public class MailService {
private final Logger logger = LoggerFactory.getLogger(this.getClass());
@Value("${spring.mail.username}")
private String from;
@Autowired
private JavaMailSender mailSender;
public void sendHtmlMail(String to, String subject, String content) {
logger.info("开始发送邮件:{},{},{}",to,subject,content);
MimeMessage message = mailSender.createMimeMessage();
MimeMessageHelper helper = null;
try {
helper = new MimeMessageHelper(message, true);
helper.setTo(to);
helper.setSubject(subject);
helper.setText(content, true);
helper.setFrom(from);
mailSender.send(message);
logger.info("发送成功");
} catch (MessagingException e) {
logger.error("发送失败:",e);
}
}
}
常见错误:
- 421 HL:ICC 该IP同时并发连接数过大
- 451 Requested mail action not token:too much fail …登录失败次数过多,被临时禁止登录
- 553 authentication is required 认证失败
- 等等,可在相关邮件服务商官网上找到相关解决方案