前言
SpringBoot實現郵件功能是非常的方便快捷的,因為SpringBoot默認有starter實現了Mail。
發送郵件應該是網站的必備功能之一,什么注冊驗證,忘記密碼或者是給用戶發送營銷信息。
最早期的時候我們會使用JavaMail相關api來寫發送郵件的相關代碼,后來spring退出了
JavaMailSender更加簡化了郵件發送的過程,在之后springboot對此進行了封裝就有了
現在的spring-boot-starter-mail。
一、基礎配置
1.1 引入依賴
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-mail</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-freemarker</artifactId>
</dependency>
1.2 獲取QQ郵箱授權碼
QQ郵箱->設置->賬戶->POP3/SMTP服務:開啟服務后會獲得QQ的授權碼.
1.3 Mail配置文件
1)qq郵箱的配置
# JavaMailSender 郵件發送的配置
spring.mail.host=smtp.qq.com
spring.mail.username=用戶qq郵箱
#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
spring.mail.default-encoding=UTF-8
2)163郵箱配置
spring.mail.host=smtp.163.com
spring.mail.username=用戶163郵箱
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
spring.mail.default-encoding=UTF-8
二、實現過程
2.1 配置文件
spring:
#郵箱配置
mail:
host: smtp.qq.com
username: 917484312@qq.com
#QQ郵箱的授權碼
password: 自己申請
default-encoding: UTF-8
properties:
mail:
smtp:
auth: true
starttls:
enable: true
required: true
freemarker:
content-type: text/html
#后綴名
suffix: .ftl
template-loader-path: classpath:/templates
charset: UTF-8
check-template-location: true
#freemarker配置
#設置一個郵件發送人
lance:
mail:
sender: 917484312@qq.com
2.2 實體Bean
/**
* @author lance(ZYH)
* @function 發送郵件-封裝接受者信息
* @date 2018-07-07 13:11
*/
@Data
public class MailBean implements Serializable {
private String recipient; //郵件接收人
private String subject; //郵件主題
private String content; //郵件內容
}
2.3 發送一個簡單格式的郵件
public void sendSimpleMail(MailBean mailBean) {
try {
SimpleMailMessage simpleMailMessage = new SimpleMailMessage();
//郵件發送人
simpleMailMessage.setFrom(MAIL_SENDER);
//郵件接收人
simpleMailMessage.setTo(mailBean.getRecipient());
//郵件主題
simpleMailMessage.setSubject(mailBean.getSubject());
//郵件內容
simpleMailMessage.setText(mailBean.getContent());
javaMailSender.send(simpleMailMessage);
} catch (Exception e) {
logger.error("郵件發送失敗", e.getMessage());
}
}
2.4 發送一個HTML格式的郵件
public void sendHTMLMail(MailBean mailBean) {
MimeMessage mimeMailMessage = null;
try {
mimeMailMessage = javaMailSender.createMimeMessage();
MimeMessageHelper mimeMessageHelper = new MimeMessageHelper(mimeMailMessage, true);
mimeMessageHelper.setFrom(MAIL_SENDER);
mimeMessageHelper.setTo(mailBean.getRecipient());
mimeMessageHelper.setSubject(mailBean.getSubject());
StringBuilder sb = new StringBuilder();
sb.append("<h1>SpirngBoot測試郵件HTML</h1>")
.append("\"<p style='color:#F00'>你是真的太棒了!</p>")
.append("<p style='text-align:right'>右對齊</p>");
mimeMessageHelper.setText(sb.toString(), true);
javaMailSender.send(mimeMailMessage);
} catch (Exception e) {
logger.error("郵件發送失敗", e.getMessage());
}
}
2.5 發送帶附件格式的郵件
public void sendAttachmentMail(MailBean mailBean) {
MimeMessage mimeMailMessage = null;
try {
mimeMailMessage = javaMailSender.createMimeMessage();
MimeMessageHelper mimeMessageHelper = new MimeMessageHelper(mimeMailMessage, true);
mimeMessageHelper.setFrom(MAIL_SENDER);
mimeMessageHelper.setTo(mailBean.getRecipient());
mimeMessageHelper.setSubject(mailBean.getSubject());
mimeMessageHelper.setText(mailBean.getContent());
//文件路徑
FileSystemResource file = new FileSystemResource(new File("src/main/resources/static/image/mail.png"));
mimeMessageHelper.addAttachment("mail.png", file);
javaMailSender.send(mimeMailMessage);
} catch (Exception e) {
logger.error("郵件發送失敗", e.getMessage());
}
}
效果:

2.6 發送帶靜態資源的郵件
public void sendInlineMail(MailBean mailBean) {
MimeMessage mimeMailMessage = null;
try {
mimeMailMessage = javaMailSender.createMimeMessage();
MimeMessageHelper mimeMessageHelper = new MimeMessageHelper(mimeMailMessage, true);
mimeMessageHelper.setFrom(MAIL_SENDER);
mimeMessageHelper.setTo(mailBean.getRecipient());
mimeMessageHelper.setSubject(mailBean.getSubject());
mimeMessageHelper.setText("<html><body>帶靜態資源的郵件內容,這個一張IDEA配置的照片:<img src='cid:picture' /></body></html>", true);
//文件路徑
FileSystemResource file = new FileSystemResource(new File("src/main/resources/static/image/mail.png"));
mimeMessageHelper.addInline("picture", file);
javaMailSender.send(mimeMailMessage);
} catch (Exception e) {
logger.error("郵件發送失敗", e.getMessage());
}
}
2.7 發送基於Freemarker模板的郵件
public void sendTemplateMail(MailBean mailBean) {
MimeMessage mimeMailMessage = null;
try {
mimeMailMessage = javaMailSender.createMimeMessage();
MimeMessageHelper mimeMessageHelper = new MimeMessageHelper(mimeMailMessage, true);
mimeMessageHelper.setFrom(MAIL_SENDER);
mimeMessageHelper.setTo(mailBean.getRecipient());
mimeMessageHelper.setSubject(mailBean.getSubject());
Map<String, Object> model = new HashMap<String, Object>();
model.put("content", mailBean.getContent());
model.put("title", "標題Mail中使用了FreeMarker");
Template template = configuration.getTemplate("mail.ftl");
String text = FreeMarkerTemplateUtils.processTemplateIntoString(template, model);
mimeMessageHelper.setText(text, true);
javaMailSender.send(mimeMailMessage);
} catch (Exception e) {
logger.error("郵件發送失敗", e.getMessage());
}
}
效果:

2.8 發送基於 thymeleaf為模板的郵件###
1)pom中導入thymeleaf的包
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-thymeleaf</artifactId>
</dependency>
2)在resorces/templates下創建emailTemplate.html
<!DOCTYPE html>
<html lang="zh" xmlns:th="http://www.thymeleaf.org">
<head>
<meta charset="UTF-8"/>
<title>Title</title>
</head>
<body>
您好,這是驗證郵件,請點擊下面的鏈接完成驗證,<br/>
<a href="#" th:href="@{ http://www.ityouknow.com/neo/{id}(id=${id}) }">激活賬號</a>
</body>
</html>
3)解析模板並發送
@Test
public void sendTemplateMail() {
//創建郵件正文
Context context = new Context();
context.setVariable("id", "006");
String emailContent = templateEngine.process("emailTemplate", context);
mailService.sendHtmlMail("ityouknow@126.com","主題:這是模板郵件",emailContent);
}
三、郵件服務的問題
3.1 郵件發送失敗
因為各種原因,總會有郵件發送失敗的情況,比如:郵件發送過於頻繁、網絡異常等。在出現這種情況的時候,
我們一般會考慮重新重試發送郵件,會分為以下幾個步驟來實現:
- 接收到發送郵件請求,首先記錄請求並且入庫。
- 調用郵件發送接口發送郵件,並且將發送結果記錄入庫。
- 啟動定時系統掃描時間段內,未發送成功並且重試次數小於3次的郵件,進行再次發送。
3.2 郵件異步發送
很多時候郵件發送並不是我們主業務必須關注的結果,比如通知類、提醒類的業務可以允許延時或者失敗。
這個時候可以采用異步的方式來發送郵件,加快主交易執行速度,在實際項目中可以采用MQ發送郵件相關
參數,監聽到消息隊列之后啟動發送郵件。
四、項目代碼地址
https://github.com/LanceToBigData/SpringBootLearning/tree/develop/SpringBoot-Mail
