郵件服務已經是基礎性服務了 ,是網站的必備功能之一,當注冊了某些網站的時候,郵箱里通常會收到一封注冊成功通知郵件或者點擊激活賬號的郵件,博客園也是如此。本文使用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的模板郵件,幾乎和博客園的一模一樣(如下圖所示):