使用 Spring Boot 開發郵件系統

電子郵件是因特網上使用得非常多的一種應用,它可以非常方便的使相隔很遠的人進行通信,它主要的特點就是操作簡單,快捷。現在的電子郵件系統以是存儲與轉發的模型爲基礎。郵件服務器接受、轉發、提交及存儲郵件。寄信人、收信人及他們的計算機都不用同時在線。寄信人和收信人只需在寄信或收信時簡短的連線到郵件服務器即可。

互聯網發展到現在,郵件服務已經成爲互聯網企業中必備功能之一,應用場景非常廣泛,比較常見的有:用戶註冊、忘記密碼、監控提醒、企業營銷等。大多數互聯網企業都會將郵件發送抽取爲一個獨立的微服務,對外提供接口來支持各種類型的郵件發送。

本篇內容會從以下幾部分來給大家介紹如何開發一個郵件系統:

  • 電子郵件的歷史

  • 發送郵件涉及到哪些協議

  • 介紹一個完整的郵件發送流程

  • 快速體驗郵件發送流程

  • 介紹如何開發文本、HTML、附件、圖片的郵件

  • 做一個郵件系統需要考慮的因素

640?wx_fmt=png

郵件歷史

我們先來回顧一下整個郵件的發展歷史。

電子郵件的發展

電子郵件發明在 70 年代,卻在 80 年纔開始有人使用。70 年代的沉寂主要是由於當時使用 Arpanet 網絡的人太少,網絡的速度也僅爲目前 56Kbps 標準速度的二十分之一,受網絡速度的限制,那時的用戶只能發送些簡短的信息,根本別想象現在那樣發送大量照片。

到 80 年代中期,個人電腦興起,電子郵件開始在電腦迷以及大學生中廣泛傳播開來;到 90 年代中期,互聯網瀏覽器誕生,全球網民人數激增,電子郵件被廣爲使用。2000 零幾年的時候,那時候沒有網盤,上大學的時候常常使用郵箱存儲東西,那時候的郵箱也主要以網易爲主;到了現在,幾乎每個人都有好幾個郵箱,QQ 郵箱、126 郵箱、公司郵箱等等,電子郵件已經成爲人們生活和工作不可或缺的一部分。

電子郵件發展歷程:

  • 1974 年,因爲 ARPANET 的推廣,電子郵件的用戶已經達到了數百人,不過他們大都是軍方用戶。自那之後,電子郵件開始了飛速的發展。Lawrence Roberts,這位當時爲 ARPANET 服務的科學家爲他的上司發明了郵件中的文件夾,以便其能夠更好地梳理自己的郵件。

  • 1975 年,南加州大學的 John Vittal 第一次發明了郵件相關的服務軟件。

  • 1977 年,現代的電子郵件系統開始出現。使用同一款軟件並且聯網了的計算機都可以使用 Tomlinson 的方法去發郵件。

  • 1982 年,有關電子郵件第一個重要的標準出臺了,這就是 SMTP(簡單郵件傳輸協議 Simple Mail Transfer Protocol),它是第一個基於互聯網基礎傳輸電子郵件的標準。時至今日它還在被人使用。而也是在這一年,「email」這個詞第一次出現了。

  • 1983 年 1 月 1 日,ARPANET 正式使用 TCP/IP 取代舊的網絡控制協議(NCP,Network Control Protocol),從而成爲今天的互聯網的基石。

  • 從 80 年代中期開始,電子郵件被廣泛使用。我國發出的第一封電子郵件就在 1987 年,是由北京計算機應用技術研究所發送到德國的。

  • 1988 年,世界上第一個商用郵件系統 Eudora 出現,發明者是美國軟件工程師 Steve Dorner。

  • 1990 年,HTML 格式的郵件出現,除了文字之外,我們也能在郵件中看到圖片了。

  • 1992 年,MIME 協議(多用途互聯網郵件擴展,Multipurpose Internet Mail Extensions)誕生,它擴展了電子郵件標準,使其能夠支援更多種形式的內容。也是在這一年,微軟在 MS-DOS 系統上,推出了 Outlook 郵件應用。

  • 1996 年,世界上第一個以網頁爲基礎的郵件應用 Hotmail 誕生,然後微軟在下一年花了 4 億美元買下了它。

  • ……

世界的第一封電子郵件

1969 年 10 月世界上的第一封電子郵件是由計算機科學家 Leonard K. 教授發給他的同事的一條簡短消息。

據《互聯網週刊》報道世界上的第一封電子郵件是由計算機科學家Leonard K.教授發給他的同事的一條簡短消息(時間應該是1969年10月),這條消息只有兩個字母:”LO”。Leonard K. 教授因此被稱爲電子郵件之父。所以第一條網上信息就是‘LO’,意思是‘你好!’”

當然這個說法也有一點爭議,另外一種說法是麻省理工學院博士 Ray Tomlinson 發送的第一封郵件,這裏不再展開討論。

中國的第一封電子郵件

1987 年 9 月 14 日中國第一封電子郵件是由“德國互聯網之父”維納·措恩與王運豐在當時的兵器工業部下屬單位—計算機應用技術研究所(簡稱 ICA)發往德國卡爾斯魯厄大學的,其內容爲德文和英文雙語,第一段大意如下:

原文:“ Across the Great Wall we can reach every corner in the world. ”

中文大意:“ 越過長城,我們可以到達世界的每一個角落。 ”

這是中國通過北京與德國卡爾斯魯厄大學之間的網絡連接,發出的第一封電子郵件。現在看這封郵件內容,頗具深意!

郵件協議

發送郵件的本質是將一個人的信息傳輸給另外一個人,那麼如何傳輸就需要商量好標準,這些標準就是協議。最初只有兩個協議:

SMTP 協議

SMTP 的全稱是 “Simple Mail Transfer Protocol”,即簡單郵件傳輸協議。它是一組用於從源地址到目的地址傳輸郵件的規範,通過它來控制郵件的中轉方式。它的一個重要特點是它能夠在傳送中接力傳送郵件,即郵件可以通過不同網絡上的主機接力式傳送。

SMTP 認證,簡單地說就是要求必須在提供了賬戶名和密碼之後纔可以登錄 SMTP 服務器,這就使得那些垃圾郵件的散播者無可乘之機。增加 SMTP 認證的目的是爲了使用戶避免受到垃圾郵件的侵擾。SMTP主要負責底層的郵件系統如何將郵件從一臺機器傳至另外一臺機器。

POP3 協議

POP3 是 Post Office Protocol 3 的簡稱,即郵局協議的第3個版本,它規定怎樣將個人計算機連接到 Internet 的郵件服務器和下載電子郵件的電子協議。它是因特網電子郵件的第一個離線協議標準,POP3 允許用戶從服務器上把郵件存儲到本地主機(即自己的計算機)上,同時刪除保存在郵件服務器上的郵件。

POP 協議支持“離線”郵件處理。其具體過程是:郵件發送到服務器上,電子郵件客戶端調用郵件客戶機程序以連接服務器,並下載所有未閱讀的電子郵件。這種離線訪問模式是一種存儲轉發服務,將郵件從郵件服務器端送到個人終端機器上,一般是 PC機或 MAC。一旦郵件發送到 PC 機或 MAC上,郵件服務器上的郵件將會被刪除。但目前的POP3郵件服務器大都可以“只下載郵件,服務器端並不刪除”,也就是改進的POP3協議。

* SMTP 和 POP3 是最初的倆個協議,隨着郵件的不斷髮展後來又增加了兩個協議:*

IMAP 協議

全稱 Internet Mail Access Protocol(交互式郵件存取協議),IMAP 是斯坦福大學在1986年開發的研發的一種郵件獲取協議,即交互式郵件存取協議,它是跟 POP3 類似郵件訪問標準協議之一。不同的是,開啓了 IMAP 後,在電子郵件客戶端收取的郵件仍然保留在服務器上,同時在客戶端上的操作都會反饋到服務器上,如:刪除郵件,標記已讀等,服務器上的郵件也會做相應的動作。所以無論從瀏覽器登錄郵箱或者客戶端軟件登錄郵箱,看到的郵件以及狀態都是一致的。

IMAP 的一個與 POP3 的區別是:IMAP 它只下載郵件的主題,並不是把所有的郵件內容都下載下來,而是你郵箱當中還保留着郵件的副本,沒有把你原郵箱中的郵件刪除,你用郵件客戶軟件閱讀郵件時才下載郵件的內容。較好支持這兩種協議的郵件客戶端有:Foxmail、Outlook 等。

Mime 協議

由於 SMTP 這個協議開始是基於純 ASCⅡ文本的,在二進制文件上處理得並不好。後來開發了用來編碼二進制文件的標準,如 MIME,以使其通過 SMTP 來傳輸。今天,大多數 SMTP 服務器都支持 8 位 MIME 擴展,它使二進制文件的傳輸變得幾乎和純文本一樣簡單。

用一張圖來看發送郵件過程中的協議使用:

640?wx_fmt=png

實線代表 [email protected] 發送郵件給 [email protected];虛線代表 [email protected] 發送郵件給 [email protected]

郵件發送流程

640?wx_fmt=png

  • 發信人在用戶代理上編輯郵件,並寫清楚收件人的郵箱地址;

  • 用戶代理根據發信人編輯的信息,生成一封符合郵件格式的郵件;

  • 用戶代理把郵件發送到發信人的的郵件服務器上,郵件服務器上面有一個緩衝隊列,發送到郵件服務器上面的郵件都會加入到緩衝隊列中,等待郵件服務器上的 SMTP 客戶端進行發送;

  • 發信人的郵件服務器使用 SMTP 協議把這封郵件發送到收件人的郵件服務器上

  • 收件人的郵件服務器收到郵件後,把這封郵件放到收件人在這個服務器上的信箱中;

  • 收件人使用用戶代理來收取郵件。首先用戶代理使用 POP3 協議來連接收件人所在的郵件服務器,身份驗證成功後,用戶代理就可以把郵件服務器上面的收件人郵箱裏面的郵件讀取出來,並展示給收件人。

這就是郵件發送的一個完整流程。

簡單使用

最早期的時候使用 JavaMail 相關 API 來開發,需要自己去封裝消息體,代碼量比較龐大;後來 Spring 推出了 JavaMailSender 簡化了郵件發送過程,JavaMailSender 提供了強大的郵件發送功能,可支持各種類型的郵件發送。

現在 Spring Boot 在 JavaMailSender 的基礎上又進行了封裝,就有了現在的 spring-boot-starter-mail,讓郵件發送流程更加簡潔和完善。下面給大家介紹如何使用 Spring Boot 發送郵件。

1、pom 包配置

引入加 spring-boot-starter-mail 依賴包:

<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-mail</artifactId>
</dependency>
</dependencies>

2、配置文件

 application.properties 中添加郵箱配置,不同的郵箱參數稍有不同,下面列舉幾個常用郵箱配置:

163郵箱配置:

spring.mail.host=smtp.163.com //郵箱服務器地址
spring.mail.username=xxx@oo.com //用戶名
spring.mail.password=xxyyooo //密碼
spring.mail.default-encoding=UTF-8

//超時時間,可選
spring.mail.properties.mail.smtp.connectiontimeout=5000
spring.mail.properties.mail.smtp.timeout=3000
spring.mail.properties.mail.smtp.writetimeout=5000

126 郵箱配置

spring.mail.host=smtp.126.com
spring.mail.username=yourEmail@126.com
spring.mail.password=yourPassword
spring.mail.default-encoding=UTF-8

qq 郵箱配置如下:

spring.mail.host=smtp.qq.com
spring.mail.username=ityouknow@qq.com
spring.mail.password=yourPassword
spring.mail.default-encoding=UTF-8

注意:測試時需要將 spring.mail.username  spring.mail.password 改成自己郵箱對應的登錄名和密碼,這裏的密碼不是郵箱的登錄密碼,是開啓 POP3 之後設置的客戶端授權密碼。

這裏以 126 爲郵件舉例,有兩個地方需要郵箱中設置:

開啓 POP3/SMTP 服務、IMAP/SMTP 服務

640?wx_fmt=png

圖片下方會有 smtp 等相關信息的配置提示。

開通設置客戶端授權密碼

640?wx_fmt=png

設置客戶端授權密碼一般需求手機驗證碼驗證。

3、文本郵件發送

Spring 已經幫我們內置了 JavaMailSender,直接在項目中引用即可。我們封裝一個 MailService 類來實現普通的郵件發送方法。

@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);
}

}
}

文本郵件抄送使用:message.copyTo(copyTo) 來實現。

  • from,即爲郵件發送者,一般設置在配置文件中 

  • to,郵件接收者,此參數可以爲數組,同時發送多人 

  • subject,郵件主題 

  • content,郵件的主體 

郵件發送者 from 一般採用固定的形式寫到配置文件中。

4、編寫 test 類進行測試

@RunWith(SpringRunner.class)
@Spring BootTest
public class MailServiceTest {

@Autowired
private MailService MailService;

@Test
public void testSimpleMail() throws Exception {
mailService.sendSimpleMail("[email protected]","這是一封簡單郵件","大家好,這是我的第一封郵件!");
}
}

稍微等待幾秒,就可以在郵箱中找到此郵件內容了。至此一個簡單的文本郵件發送就完成了。

640?wx_fmt=png

富文本郵件

在日常使用的過程中,我們通常在郵件中加入圖片或者附件來豐富郵件的內容,下面講介紹如何使用 Spring Boot 來發送富文本郵件。

發送 HTML 格式郵件

郵件發送支持以 HTML 語法去構建自定義的郵件格式,Spring Boot 支持使用 HTML 發送郵件。

我們在 MailService 中添加支持 HTML 郵件發送的方法.

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);
}
}

富文本郵件抄送使用:helper.addCc(cc) 來實現。

和文本郵件發送代碼對比,富文本郵件發送使用 MimeMessageHelper 類。MimeMessageHelper 支持發送複雜郵件模板,支持文本、附件、HTML、圖片等,接下來會一一使用到。

在測試類中構建 HTML 內容,測試發送

@Test
public void testHtmlMail() throws Exception {
String content="<html>\n" +
"<body>\n" +
" <h3>hello world ! 這是一封html郵件!</h3>\n" +
"</body>\n" +
"</html>";
mailService.sendHtmlMail("[email protected]","這是一封HTML郵件",content);
}

郵件內容大寫了一段話,下面爲接收到的效果:

640?wx_fmt=png

由此我們發現發送 HTML 郵件,就是需要拼接一段 HTML 的 String 字符串交給 MimeMessageHelper 來處理,最後由郵件客戶端負責渲染顯示內容。

發送帶附件的郵件

在 MailService 添加 sendAttachmentsMail 方法,發送帶附件的郵件主要是使用 FileSystemResource 對文件進行封裝,在添加到 MimeMessageHelper 中。

public void sendAttachmentsMail(String to, String subject, String content, String filePath){
MimeMessage message = mailSender.createMimeMessage();

try {
MimeMessageHelper helper = new MimeMessageHelper(message, true);
helper.setFrom(from);
helper.setTo(to);
helper.setSubject(subject);
helper.setText(content, true);

FileSystemResource file = new FileSystemResource(new File(filePath));
String fileName = file.getFilename();
helper.addAttachment(fileName, file);
//helper.addAttachment("test"+fileName, file);

mailSender.send(message);
logger.info("帶附件的郵件已經發送。");
} catch (MessagingException e) {
logger.error("發送帶附件的郵件時發生異常!", e);
}
}

添加多個附件可以使用多條 helper.addAttachment(fileName, file)

在測試類中添加測試方法

@Test
public void sendAttachmentsMail() {
String filePath="e:\\temp\\fastdfs-client-java-5.0.0.jar";
mailService.sendAttachmentsMail("[email protected]", "主題:帶附件的郵件", "有附件,請查收!", filePath);
}

附件可以是圖片、壓縮包、Word 等任何文件,但是郵件廠商一般都會對附件大小有限制,太大的附件建議使用網盤上傳後,在郵件中給出鏈接。

效果圖如下:

640?wx_fmt=png

發送帶靜態資源的郵件

郵件中的靜態資源一般指圖片,在 MailService 添加 sendInlineResourceMail 方法。

public void sendInlineResourceMail(String to, String subject, String content, String rscPath, String rscId){
MimeMessage message = mailSender.createMimeMessage();

try {
MimeMessageHelper helper = new MimeMessageHelper(message, true);
helper.setFrom(from);
helper.setTo(to);
helper.setSubject(subject);
helper.setText(content, true);

FileSystemResource res = new FileSystemResource(new File(rscPath));
helper.addInline(rscId, res);

mailSender.send(message);
logger.info("嵌入靜態資源的郵件已經發送。");
} catch (MessagingException e) {
logger.error("發送嵌入靜態資源的郵件時發生異常!", e);
}
}

在測試類中添加測試方法

@Test
public void sendInlineResourceMail() {
String rscId = "neo006";
String content="<html><body>這是有圖片的郵件:<img src=\'cid:" + rscId + "\' ></body></html>";
String imgPath = "e:\\temp\\weixin.jpg";

mailService.sendInlineResourceMail("[email protected]", "主題:這是有圖片的郵件", content, imgPath, rscId);
}

添加多個圖片可以使用多條 <img src='cid:" + rscId + "' >  helper.addInline(rscId, res) 來實現

效果圖如下:

640?wx_fmt=png

以上是郵件發送的基礎服務,已演示支持各種類型郵件。

郵件系統

如果只是想在系統中做一個郵件工具類的話,以上的內容基本就可以滿足要求了。要做成一個郵件系統的話還需要考慮以下幾方面:

  • 對外提供發送郵件的服務接口

  • 固定格式郵件是否考慮使用模板

  • 發送郵件時出現網絡錯誤,是否考慮適當的重試機制

  • 郵件系統是否考慮異步化,提升服務響應時間

  • 是否開發郵件後臺管理系統,開發出對應的管理軟件,通過頁面發送郵件,統計發送郵件成功率等數據。

  • 常見異常處理措施

對外提供接口

作爲一個獨立的郵件系統,需要對外提供接口調用,我們以簡單文本郵件爲例做個演示:

首先需要定義個實例返回對象:

public class MailResult {
private String rspCode;
private String rspMsg;

public MailResult() {
this.rspCode = "00";
this.rspMsg = "發送成功";
}
//省略 setter/getter
}

默認成功的返回碼爲:00,返回消息爲:發送成功。

創建一個 MailController 類對外提供 HTTP 請求接口。

@RestController
public class MailController {
private final Logger logger = LoggerFactory.getLogger(this.getClass());
@Resource
private MailService mailService;

@RequestMapping("/sendSimpleMail")
public MailResult sendSimpleMail(String to, String subject, String content) {
MailResult result=new MailResult();
if(StringUtils.isEmpty(to) || !to.contains("@")){
result.setRspCode("01");
result.setRspCode("手機人郵件格式不正確");
}
if(StringUtils.isEmpty(content) ){
result.setRspCode("03");
result.setRspCode("郵件正文不能爲空");
}
try {
mailService.sendSimpleMail(to,subject,content);
logger.info("簡單郵件已經發送。");
} catch (Exception e) {
result.setRspCode("04");
result.setRspCode("郵件發送出現異常");
logger.error("sendSimpleMail Exception ", e);
}
return result;
}
}

外部請求過來時首先進行參數校驗,如果參數有誤返回請求;發送郵件出現異常時返回錯誤,正常情況下返回 00;注意在 Service 層如果對異常信息進行了捕獲的話,需要將異常信息拋到上層。

try {
mailSender.send(message);
logger.info("簡單郵件已經發送。");
} catch (Exception e) {
logger.error("發送簡單郵件時發生異常!", e);
throw e;
}

類似上述代碼。

按照這個思路也可以提供發送帶圖片、帶附件的郵件,同時也可以封裝發送多人郵件,羣發郵件等複雜情況。

郵件模板

通常我們使用郵件發送服務的時候,都會有一些固定的場景,比如重置密碼、註冊確認等,給每個用戶發送的內容可能只有小部分是變化的。所以,很多時候我們會使用模板引擎來爲各類郵件設置成模板,這樣我們只需要在發送時去替換變化部分的參數即可。

我們會經常收到這樣的郵件:

尊敬的 neo 用戶:

恭喜您註冊成爲xxx網的用戶,同時感謝您對xxx的關注與支持並歡迎您使用xx的產品與服務。
...

郵件正文只有 neo 這個用戶名在變化,郵件其它內容均不變,如果每次發送郵件都需拼接 HTML 代碼,程序不夠優雅,並且每次郵件正文有變化都需修改代碼非常不方便。因此對於這類郵件,都建議做成郵件模板來處理,模板的本質很簡單,就是在模板中替換變化的參數,轉換爲 HTML 字符串即可,這裏以 Thymeleaf 爲例來演示。

Thymeleaf 是 Spring 官方推薦的前端模板引擎,類似 Velocity、FreeMarker 等模板引擎,相較與其他的模板引擎,Thymeleaf 開箱即用的特性。它提供標準和 Spring 標準兩種方言,可以直接套用模板實現 JSTL、 OGNL 表達式效果,避免每天套模板、該 Jstl、改標籤的困擾。Thymeleaf 在有網絡和無網絡的環境下皆可運行,即它可以讓美工在瀏覽器查看頁面的靜態效果,也可以讓程序員在服務器查看帶數據的動態頁面效果。

下面我們來演示使用 Thymeleaf 製作郵件模板。

1、添加依賴包

<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-thymeleaf</artifactId>
</dependency>

2、在 resorces/templates 下創建 emailTemplate.html

emailTemplate.html 文件內容即爲郵件的正文內容模板。

<!DOCTYPE html>
<html lang="zh" xmlns:th="http://www.thymeleaf.org">
<head>
<meta charset="UTF-8"/>
<title>郵件模板</title>
</head>
<body>
您好,感謝您的註冊,這是一封驗證郵件,請點擊下面的鏈接完成註冊,感謝您的支持<br/>
<a href="#" th:href="@{http://www.ityouknow.com/register/{id}(id=${id}) }">激活賬號</a>
</body>
</html>

我們發現上述的模板中只有 id 是一個動態的值,發送過程中會根據傳入的 id 值來替換鏈接中的 {id}

3、解析模板併發送

@Test
public void sendTemplateMail() {
//創建郵件正文
Context context = new Context();
//設置模板需要替換的參數
context.setVariable("id", "006");
//使用 templateEngine 替換掉動態參數生產出最後的 HTML 內容。
String emailContent = templateEngine.process("emailTemplate", context);
//最後調用 sendHtmlMail 發送郵件
mailService.sendHtmlMail("[email protected]","主題:這是模板郵件",emailContent);
}

我們發現最後調用的還是 sendHtmlMail 的方法,郵件模板的作用只是處理 HTML 生成部分,通過 Thymeleaf 模板引擎解析固定的模板,再更具參數來動態替換其中的變量,最後通過前面的 HTML 發送的方法發送郵件。

效果圖如下:

640?wx_fmt=png

點擊“激活賬號”跳轉的鏈接爲:http://www.ityouknow.com/register/006

發送失敗

因爲各種原因,總會有郵件發送失敗的情況,比如:郵件發送過於頻繁、網絡異常等。在出現這種情況的時候,我們一般會考慮重新重試發送郵件,會分爲以下幾個步驟來實現:

  1. 接收到發送郵件請求,首先記錄請求並且入庫。

  2. 調用郵件發送接口發送郵件,並且將發送結果記錄入庫。

  3. 啓動定時系統掃描時間段內,未發送成功並且重試次數小於3次的郵件,進行再次發送.

  4. 重新發送郵件的時間,建議以 2 的次方間隔時間,比如:2、4、8、16 … 

常見的錯誤返回碼:

  • 421 HL:ICC 該IP同時併發連接數過大,超過了網易的限制,被臨時禁止連接。

  • 451 Requested mail action not taken: too much fail authentication 登錄失敗次數過多,被臨時禁止登錄。請檢查密碼與帳號驗證設置

  • 553 authentication is required,密碼配置不正確

  • 554 DT:SPM 發送的郵件內容包含了未被許可的信息,或被系統識別爲垃圾郵件。請檢查是否有用戶發送病毒或者垃圾郵件;

  • 550 Invalid User 請求的用戶不存在

  • 554 MI:STC 發件人當天內累計郵件數量超過限制,當天不再接受該發件人的投信。

如果使用一個郵箱頻繁發送相同內容郵件,也會被認定爲垃圾郵件,報 554 DT:SPM 錯誤

如果使用網易郵箱可以查看這裏的提示:企業退信的常見問題?

其它

異步發送

很多時候郵件發送並不是主業務必須關注的結果,比如通知類、提醒類的業務可以允許延時或者失敗。這個時候可以採用異步的方式來發送郵件,加快主交易執行速度。在實際項目中可以採用消息中間件 MQ 發送郵件,具體做法是創建一個郵件發送的消息隊列,在業務中有需要用到郵件發送功能時,給對應消息隊列按照規定參數發送一條消息,郵件系統監聽此隊列,當有消息過來時,處理郵件發送的邏輯。

管理後臺

考慮做一個完善的郵件系統,可以設計一個獨立的郵件管理後臺,不但可以讓系統之間調用時使用,也可以提供圖形化界面讓公司的運營、市場部的同事來發送郵件,查詢郵件的發送進度,統計郵件發送成功率。也可以設置一些代碼鉤子,統計用戶點擊固定鏈接次數,方便公司營銷人員監控郵件營銷轉化率。

一個非常完善的郵件系統需要考慮的因素非常多,比如是否設置白名單、黑名單來做郵件接收人的過濾機制,是否給用戶提供郵件退訂的接口等。因此在初期郵件發送的基本功能完成之後,再結合公司業務,快速迭代的逐步完善郵件系統,是一個推薦的做法。

總結

使用 Spring Boot 集成發送郵件的功能非常簡單,只需要簡單編碼就可以實現發送普通文本郵件、帶附件郵件、HTML 格式郵件、帶圖片郵件等。如果需要做成一個郵件系統還需要考慮很多因素,比如:郵箱發送失敗重試機制、防止郵件被識別爲垃圾郵件,固定時間內發送郵件的限制等。在微服務架構中,常常將一些基礎功能下沉下來,作爲獨立的服務來使用,郵件系統作爲平臺的基礎功能,特別適合做爲獨立的微服務來支持整個系統。

點擊這裏下載源碼

參考:

   https://www.geekpark.net/news/214789



640?wx_fmt=jpeg




如果你覺得還不錯

記得點“愛心”讓我知道喲

640?wx_fmt=gif


發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章