邮件服务已经是基础性服务了 ,是网站的必备功能之一,当注册了某些网站的时候,邮箱里通常会收到一封注册成功通知邮件或者点击激活账号的邮件,博客园也是如此。本文使用Spring Boot,通过QQ邮箱来模仿博客园发送一封通知邮件。
博客园发送的“欢迎您加入博客园”的主题邮件如图所示。这种通知邮件,只有登录用户名在变化,其它邮件内容均不变,很适合用邮件模板来处理。
模板可以实现显示与数据分离,将模板文件和数据通过模板引擎生成最终的HTML代码。
Thymeleaf是一个适用于Web和独立环境的现代服务器端Java模板引擎,能够处理HTML,XML,JavaScript,CSS甚至纯文本。Thymeleaf由于使用了标签属性做为语法,模版页面直接用浏览器渲染,与其它模板引擎(比如Freemaker)相比,Thymeleaf最大的特点是能够直接在浏览器中打开并正确显示模板页面,而不需要启动整个Web应用。
Thymeleaf作为Spring官方推荐的模板引擎,Spring boot对Thymeleaf支持比较友好,配置简单,这里使用Thymeleaf作为模板引擎。
下面正式开始实现仿博客园发送通知邮件。
1. 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-thymeleaf</artifactId>
</dependency>
2. application.property配置邮箱和thymelea模板
我使用的是QQ邮箱,需要获得QQ邮箱的授权码。
关于QQ邮箱生成授权码:进入QQ邮箱 --> 邮箱设置 --> 账户 --> POP3/IMAP/SMTP/Exchange/CardDAV/CalDAV服务 --> 生成授权码 --> 手机发送验证短信 -->得到授权码
spring.mail.host=smtp.qq.com
spring.mail.username=QQ邮箱
spring.mail.password=授权码
spring.mail.properties.mail.smtp.auth=true
spring.mail.properties.mail.smtp.starttls.enable=true
spring.mail.properties.mail.smtp.starttls.required=true
#thymelea模板配置
spring.thymeleaf.prefix=classpath:/templates/
spring.thymeleaf.suffix=.html
spring.thymeleaf.mode=HTML
spring.thymeleaf.encoding=UTF-8
spring.thymeleaf.servlet.content-type:text/html
#热部署文件,页面不产生缓存,及时更新
spring.thymeleaf.cache=false
spring.resources.chain.strategy.content.enabled=true
spring.resources.chain.strategy.content.paths=/**
3. 编写Service及其实现
Service中有两个方法:
sendSimpleMail用于发送简单的文本邮件,是一个比较基础的案例。
sendHtmlMail用于发送HTML邮件,发送通知邮件用的就是这个方法。其实模板邮件也就是HTML邮件中的一个子类。
MailService:
public interface MailService {
public void sendSimpleMail(String to, String subject, String content);
public void sendHtmlMail(String to, String subject, String content);
}
MailServiceImpl:
@Component
public class MailServiceImpl implements MailService {
private final Logger logger = LoggerFactory.getLogger(this.getClass());
@Autowired
private JavaMailSender mailSender;
@Value("${spring.mail.username}")
private String from;
@Override
public void sendSimpleMail(String to, String subject, String content) {
SimpleMailMessage message = new SimpleMailMessage();
message.setFrom(from);
message.setTo(to);//邮件接收者
message.setSubject(subject);//邮件主题
message.setText(content);//邮件内容
try {
mailSender.send(message);
logger.info("发送简单邮件成功!");
} catch (Exception e) {
logger.error("发送简单邮件时发生异常!", e);
}
}
@Override
public void sendHtmlMail(String to, String subject, String content) {
MimeMessage message = mailSender.createMimeMessage();
try {
//true表示需要创建一个multipart message
MimeMessageHelper helper = new MimeMessageHelper(message, true);
helper.setFrom(from);
helper.setTo(to);
helper.setSubject(subject);
helper.setText(content, true);
mailSender.send(message);
logger.info("发送HTML邮件成功!");
} catch (MessagingException e) {
logger.error("发送HTML邮件时发生异常!", e);
}
}
}
4. 创建模板
在resorces/templates下创建emailTemplate.html模板,与模板配置中的spring.thymeleaf.prefix=classpath:/templates/对应,不然会找不到模板。
关于Thymeleaf的使用这里简单介绍一下:
引入命名空间:<html xmlns:th="http://www.thymeleaf.org">。不同的约束文档中,可能会出现不同含义的相同标记名称,引入名称空间可以避免混淆和冲突。
访问数据:#{user.name}
访问变量:${today}
输出URL: <a href="#" th:href="@{https://www.cnblogs.com}">博客园</a>
更多详情的说明和规则请参见:Thymeleaf官方文档
emailTemplate.html:
<!DOCTYPE html>
<html lang="zh" xmlns:th="http://www.thymeleaf.org">
<head>
<meta charset="UTF-8" />
<title>欢迎您加入博客园</title>
</head>
<body>
<p>您好,您在博客园的帐户激活成功,您的登录用户名是:<span th:text="${username}"></span>。</p>
<p>--</p>
<div>博客园(
<a th:href="@{https://www.cnblogs.com }">www.cnblogs.com</a>
) - 开发者的网上家园</div>
<p>代码改变世界!</p>
</body>
</html>
5. JUnit单元测试
使用Junit进行单元测试,pom.xml中已经默认配置好了,需要编写测试类和测试方法。测试类以xxxTest.java命名,测试方法上面加
@Test注解就可以使用了。具体代码如下:
@RunWith(SpringRunner.class)
@SpringBootTest
public class EmailTest {
@Autowired
private MailService mailService;
@Autowired
private TemplateEngine templateEngine;
@Test
public void testSendSimpleMail() throws Exception {
mailService.sendSimpleMail("xxx@qq.com", "测试发送简单文本邮件", "测试发送简单文本邮件");
}
@Test
public void testSendTemplateMail() {
Context context = new Context();
context.setVariable("username", "shangguanhao");
String emailContent = templateEngine.process("emailTemplate", context);
mailService.sendHtmlMail("xxx@qq.com", "欢迎您加入博客园", emailContent);
}
}
进行Junit测试,就可以发送一个简答的文本邮件和一个HTML的模板邮件,几乎和博客园的一模一样(如下图所示):
完整代码:https://github.com/shangguanhao/spring-boot-example/tree/master/mail