Spring Boot (十二): Spring Boot 郵件服務
最早我們發郵件的時候是使用 JavaMail 來發送郵件,而在 Spring Boot 中, Spring Boot 幫我們將 JavaMail 封裝好了,是可以直接拿來使用的。
1. 依賴檔案 pom.xml
程式碼清單:spring-boot-mail/pom.xml
***
<dependencies> <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> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-test</artifactId> <scope>test</scope> </dependency> </dependencies>
- spring-boot-starter-thymeleaf 引入這個模版引擎是因為我們在傳送郵件的時候,各種格式使用 HTML 的方式更容易實現,同樣我們也可以使用 freeMark , Spring Boot 同樣為我們提供了依賴包。
2. 配置檔案 application.yml
程式碼清單:
***
server: port: 8080 spring: application: name: spring-boot-mail mail: host: smtp.qq.com username: 136736247 password: xxxxxx default-encoding: UTF-8 fromAddr: [email protected] nickName: inwsy
這裡我使用 QQ 郵箱作為郵件的傳送方,其中的 password
並不是我們的 QQ 密碼,這個密碼需要我們在 QQ 郵箱的設定裡面自己申請的。如下圖:
其中的 spring.mail.fromAddr
和 spring.mail.nickName
這兩個配置是我自己配置的,並不是官方的配置,後續我會在程式碼中讀這兩個配置項。
3. 簡易郵件傳送
3.1 實現類
程式碼清單:spring-boot-mail/src/main/java/com/springboot/springbootmail/service/impl/MailServiceImpl.java
***
@Service public class MailServiceImpl implements MailService { private final Logger logger = LoggerFactory.getLogger(this.getClass()); @Autowired private JavaMailSender javaMailSender; @Value("${spring.mail.fromAddr}") private String from; @Value("${spring.mail.nickName}") private String nickName; @Override public void sendSimpleEmail(String to, String subject, String content) { SimpleMailMessage simpleMailMessage = new SimpleMailMessage(); simpleMailMessage.setFrom(nickName + "<" + from + ">"); simpleMailMessage.setTo(to); simpleMailMessage.setSubject(subject); simpleMailMessage.setText(content); try{ javaMailSender.send(simpleMailMessage); logger.info("簡易郵件傳送成功"); } catch(Exception e) { logger.error("簡易郵件傳送異常", e); } } }
3.2 測試類
程式碼清單:spring-boot-mail/src/test/java/com/springboot/springbootmail/SpringBootMailApplicationTests.java
***
@Autowired
MailService mailService;
@Test
public void sendSimpleEmail() {
mailService.sendSimpleEmail("[email protected]", "測試郵件題目", "測試郵件內容");
}
這裡郵件傳送至本人的 Hotmail 郵箱。
4. 傳送 HTML 格式的郵件
4.1 實現類
程式碼清單:spring-boot-mail/src/main/java/com/springboot/springbootmail/service/impl/MailServiceImpl.java
***
@Override
public void sendHTMLEmail(String to, String subject, String content) {
MimeMessage message = javaMailSender.createMimeMessage();
try {
MimeMessageHelper messageHelper = new MimeMessageHelper(message, true);
messageHelper.setFrom(new InternetAddress(from, nickName, "UTF-8"));
messageHelper.setTo(to);
messageHelper.setSubject(subject);
messageHelper.setText(content, true);
javaMailSender.send(message);
logger.info("HTML 模版郵件傳送成功");
} catch (MessagingException e) {
logger.error("HTML 模版郵件傳送失敗", e);
} catch (UnsupportedEncodingException e) {
logger.error("收件地址編碼異常", e);
}
}
4.2 頁面模版
程式碼清單:spring-boot-mail/src/main/resources/templates/email.html
***
<!DOCTYPE html>
<html lang="zh" xmlns:th="http://www.thymeleaf.org">
<head>
<meta charset="UTF-8"/>
<title>郵件模版</title>
</head>
<body>
這是郵件模版生成的郵件,可以點選連結檢視詳情。
<a href="#" th:href="@{ http://www.geekdigging.com/ }">檢視詳情。</a>
當前的Code為:<span th:text="${code}"></span>
</body>
</html>
這裡添加了動態內容 code ,在日常的開發中,我們使用傳送驗證碼,動態生成內容是很有必要的。
4.3 測試類
程式碼清單:spring-boot-mail/src/test/java/com/springboot/springbootmail/SpringBootMailApplicationTests.java
***
@Test
public void sendHTMLTemplateMail() {
Context context = new Context();
context.setVariable("code", "123456");
String emailHTMLContent = templateEngine.process("email", context);
mailService.sendHTMLEmail("[email protected]", "測試 HTML 模版郵件", emailHTMLContent);
}
5. 傳送帶附件的郵件
5.1 實現類
程式碼清單:spring-boot-mail/src/main/java/com/springboot/springbootmail/service/impl/MailServiceImpl.java
***
@Override
public void sendAttachmentsMail(String to, String subject, String content, String fileName, String filePath) {
MimeMessage message = javaMailSender.createMimeMessage();
try {
MimeMessageHelper messageHelper = new MimeMessageHelper(message, true);
messageHelper.setFrom(new InternetAddress(from, nickName, "UTF-8"));
messageHelper.setTo(to);
messageHelper.setSubject(subject);
messageHelper.setText(content, true);
FileSystemResource file = new FileSystemResource(new File(filePath));
messageHelper.addAttachment(fileName, file);
javaMailSender.send(message);
logger.info("帶附件郵件傳送成功");
} catch (MessagingException e) {
logger.error("帶附件郵件傳送失敗", e);
} catch (UnsupportedEncodingException e) {
logger.error("收件地址編碼異常", e);
}
}
注意: 如果需要傳送多個附件,寫多個 messageHelper.addAttachment(fileName, file);
即可。
5.2 測試類
程式碼清單:spring-boot-mail/src/test/java/com/springboot/springbootmail/SpringBootMailApplicationTests.java
***
@Test
public void sendAttachmentsMail() {
String fileName = "圖片.jpg";
String filePath = "C:\\Users\\inwsy\\Downloads\\0370279582fe3e2a8012060c896a5dd.jpg";
mailService.sendAttachmentsMail("[email protected]", "測試帶附件的郵件", "詳細請查閱附件", fileName, filePath);
}
6. 小結
在實際的開發過程中,郵件傳送失敗是一件比較經常出現的事情,比如:網路堵塞、對方拒收等情況,一般在郵件系統的設計中,可以先將要傳送的資料寫入資料中,等傳送完成後再修改標記位,再增加一個保障機制,例如增加一個定時任務,將一段時間內,傳送失敗並重試次數小於一定閥值的內容再次進行傳送,如果郵件系統的壓力過大,可以選擇使用非同步的方式來進行傳送,比如使用訊息佇列進行承壓。
7. 示例程式碼
示例程式碼-Github
示例程式碼-Gitee
7. 參考
http://www.ityouknow.com/springboot/2017/05/06/spring-boot-mail.h