Spring Boot实现仿博客园发送通知邮件
邮件服务已经是基础性服务了 ,是网站的必备功能之一,当注册了某些网站的时候,邮箱里通常会收到一封注册成功通知邮件或者点击激活账号的邮件,博客园也是如此。本文使用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邮箱的授权码。
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的模板邮件,几乎和博客园的一模一样(如下图所示):