springboot集成邮箱功能
1. 寫在前面
我們都知道,如果系統(tǒng)出現(xiàn)預(yù)警,或者有一些監(jiān)控需求,我們可以通過發(fā)送短信或者郵件來進(jìn)行通知,本篇文章呢,我就打算來講解一下SpringBoot的郵件服務(wù)。我們都知道發(fā)送郵件應(yīng)該是網(wǎng)站的必備功能之一,什么注冊(cè)驗(yàn)證,忘記密碼或者是給用戶發(fā)送營(yíng)銷信息。以前我們會(huì)使用 JavaMail 相關(guān) api 來寫發(fā)送郵件的相關(guān)代碼,后來 Spring 推出了 JavaMailSender 更加簡(jiǎn)化了郵件發(fā)送的過程,在之后 Spring Boot 對(duì)此進(jìn)行了封裝就有了現(xiàn)在的 spring-boot-starter-mail,如果你看了我前面的文章的話,就會(huì)知道,SpringBoot把大部分的需求封裝成了一個(gè)個(gè)場(chǎng)景啟動(dòng)器,而mail也就是相應(yīng)的場(chǎng)景啟動(dòng)器。
2. 了解郵件服務(wù)
經(jīng)常出現(xiàn)和郵件相關(guān)的協(xié)議是SMTP、IMAP和POP3,所以在這里我們首先來認(rèn)識(shí)了解這三個(gè)協(xié)議。
SMTP全稱為Simple Mail Transfer Protocol(簡(jiǎn)單郵件傳輸協(xié)議),它是一組用于從源地址到目的地址傳輸郵件的規(guī)范,通過它來控制郵件的中轉(zhuǎn)方式。SMTP認(rèn)證要求必須提供賬號(hào)和密碼才能登陸服務(wù)器,其設(shè)計(jì)目的在于避免用戶受到垃圾郵件的侵?jǐn)_。
IMAP全稱為Internet Message Access Protocol(互聯(lián)網(wǎng)郵件訪問協(xié)議),IMAP允許從郵件服務(wù)器上獲取郵件的信息、下載郵件等。IMAP與POP類似,都是一種郵件獲取協(xié)議。
POP3全稱為Post Office Protocol 3(郵局協(xié)議),POP3支持客戶端遠(yuǎn)程管理服務(wù)器端的郵件。POP3常用于“離線”郵件處理,即允許客戶端下載服務(wù)器郵件,然后服務(wù)器上的郵件將會(huì)被刪除。目前很多POP3的郵件服務(wù)器只提供下載郵件功能,服務(wù)器本身并不刪除郵件,這種屬于改進(jìn)版的POP3協(xié)議。
那么問題來了,IMAP和POP3協(xié)議有什么不同呢?兩者最大的區(qū)別在于,IMAP允許雙向通信,即在客戶端的操作會(huì)反饋到服務(wù)器上,例如在客戶端收取郵件、標(biāo)記已讀等操作,服務(wù)器會(huì)跟著同步這些操作。而對(duì)于POP協(xié)議雖然也允許客戶端下載服務(wù)器郵件,但是在客戶端的操作并不會(huì)同步到服務(wù)器上面的,例如在客戶端收取或標(biāo)記已讀郵件,服務(wù)器不會(huì)同步這些操作。
3. SpringBoot相關(guān)類
SpringBoot中針對(duì)郵件服務(wù)的兩個(gè)工具類是,JavaMailSender和JavaMailSenderImpl,它們是Spring官方提供的集成郵件服務(wù)的接口和實(shí)現(xiàn)類,以簡(jiǎn)單高效的設(shè)計(jì)著稱,目前是Java后端發(fā)送郵件和集成郵件服務(wù)的主流工具。那如何通過JavaMailSenderImpl發(fā)送郵件?非常簡(jiǎn)單,直接在業(yè)務(wù)類注入JavaMailSenderImpl并調(diào)用send方法發(fā)送郵件。其中簡(jiǎn)單郵件可以通過SimpleMailMessage來發(fā)送郵件,而復(fù)雜的郵件(例如添加附件)可以借助MimeMessageHelper來構(gòu)建MimeMessage發(fā)送郵件。
我們不難理解,SpringBoot對(duì)于郵件服務(wù)能做到開箱即用,其實(shí)就是基于官方內(nèi)置的自動(dòng)配置,翻看源碼可知曉郵件自動(dòng)配置類(MailSenderPropertiesConfiguration) 為上下文提供了郵件服務(wù)實(shí)例(JavaMailSenderImpl)。
4. 具體教程
4.1、pom配置
首先我們創(chuàng)建一個(gè)新的項(xiàng)目,只要包含最基本的web場(chǎng)景就可以了,然后我們?cè)趐om.xml中引入依賴就可以了,依賴如下:
<dependencies><dependency> <groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-mail</artifactId></dependency> </dependencies>接著,我們?cè)赼pplication.properties主配置文件中對(duì)mail進(jìn)行相關(guān)的配置,配置內(nèi)容如下,我做了相關(guān)注釋
spring.mail.host=smtp.163.com spring.mail.username=amazing spring.mail.password=xxxxxx #這里填的不是賬號(hào)密碼,是的第三方登錄校驗(yàn)碼 spring.mail.default-encoding=UTF-8 mail.fromMail.address=amazing@163.com上面的郵箱服務(wù)器的地址,我這里放出一下常用有限發(fā)郵箱服務(wù)器地址
QQ郵箱(mail.qq.com): POP3服務(wù)器地址:pop.qq.com(端口:110) SMTP服務(wù)器地址:smtp.qq.com(端口:25) SMTP服務(wù)器需要身份驗(yàn)證。網(wǎng)易郵箱(163.com): POP3服務(wù)器地址:pop.163.com(端口:110) SMTP服務(wù)器地址:smtp.163.com(端口:25)谷歌郵箱(google.com): POP3服務(wù)器地址:pop.gmail.com(SSL啟用端口:995) SMTP服務(wù)器地址:smtp.gmail.com(SSL啟用端口:587)阿里云郵箱(mail.aliyun.com): POP3服務(wù)器地址:pop3.aliyun.com(SSL加密端口:995;非加密端口:110) SMTP服務(wù)器地址:smtp.aliyun.com(SSL加密端口:465;非加密端口:25) IMAP服務(wù)器地址:imap.aliyun.com(SSL加密端口:993;非加密端口:143)新浪郵箱(sina.com): POP3服務(wù)器地址:pop3.sina.com.cn(端口:110) SMTP服務(wù)器地址:smtp.sina.com.cn(端口:25)4.2、簡(jiǎn)單使用
這樣就完成了我們SpringBoot使用郵件服務(wù)的基本配置,那么接下來我們簡(jiǎn)單使用一下,首先編寫Service,目錄結(jié)構(gòu)如下
編寫 test 類進(jìn)行測(cè)試,至此一個(gè)簡(jiǎn)單的文本發(fā)送就完成了。
4.3、豐富郵件內(nèi)容
但是在正常使用的過程中,我們通常在郵件中加入圖片或者附件來豐富郵件的內(nèi)容,下面講介紹如何使用 Spring Boot 來發(fā)送豐富的郵件。
發(fā)送 html 格式郵件
其它都不變?cè)?MailService 添加 sendHtmlMail 方法
在測(cè)試類中構(gòu)建 html 內(nèi)容,測(cè)試發(fā)送
@Test public void testHtmlMail() throws Exception {String content="<html>\n" +"<body>\n" +" <h3>hello world ! 這是一封Html郵件!</h3>\n" +"</body>\n" +"</html>";MailService.sendHtmlMail("xxxxxx@163.com","test simple mail",content); }發(fā)送帶附件的郵件
還是老樣子,在 MailService 添加 sendAttachmentsMail 方法。
添加多個(gè)附件可以使用多條 helper.addAttachment(fileName, file),然后在測(cè)試類中添加測(cè)試方法
@Test public void sendAttachmentsMail() {String filePath="e:\\tmp\\application.log";mailService.sendAttachmentsMail("xxxxx@163.com", "主題:帶附件的郵件", "有附件,請(qǐng)查收!", filePath); }發(fā)送帶靜態(tài)資源的郵件
郵件中的靜態(tài)資源一般就是指圖片,在 MailService 添加 sendAttachmentsMail 方法。
在測(cè)試類中添加測(cè)試方法
@Test public void sendInlineResourceMail() {String rscId = "neo006";String content="<html><body>這是有圖片的郵件:<img src=\'cid:" + rscId + "\' ></body></html>";String imgPath = "C:\\Users\\summer\\Pictures\\favicon.png";mailService.sendInlineResourceMail("XXXXX@163.com", "主題:這是有圖片的郵件", content, imgPath, rscId); }添加多個(gè)圖片可以使用多條 <img src='cid:" + rscId + "' > 和 helper.addInline(rscId, res)來實(shí)現(xiàn)
4.5、總結(jié)步驟
參考文章
5.郵件系統(tǒng)
上面發(fā)送郵件的基礎(chǔ)服務(wù)就這些了,但是如果我們要做成一個(gè)郵件系統(tǒng)的話還需要考慮以下幾個(gè)問題,首先是郵件模板的問題,我們會(huì)經(jīng)常收到類似這樣的郵件
其中只有 neo 這個(gè)用戶名在變化,其它郵件內(nèi)容均不變,如果每次發(fā)送郵件都需要手動(dòng)拼接的話會(huì)不夠優(yōu)雅,并且每次模板的修改都需要改動(dòng)代碼的話也很不方便,因此對(duì)于這類郵件需求,都建議做成郵件模板來處理。模板的本質(zhì)很簡(jiǎn)單,就是在模板中替換變化的參數(shù),轉(zhuǎn)換為 html 字符串即可,這里以thymeleaf為例來演示,第一步當(dāng)然是導(dǎo)入thymeleaf的包啦。
<dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-thymeleaf</artifactId> </dependency>然后在在 resorces/templates 下創(chuàng)建 emailTemplate.html
<!DOCTYPE html> <html lang="zh" xmlns:th="http://www.thymeleaf.org"><head><meta charset="UTF-8"/><title>Title</title></head><body>您好,這是驗(yàn)證郵件,請(qǐng)點(diǎn)擊下面的鏈接完成驗(yàn)證,<br/><a href="#" th:href="@{ http://www.xxx.com/neo/{id}(id=${id}) }">激活賬號(hào)</a></body> </html> @Test public void sendTemplateMail() {//創(chuàng)建郵件正文Context context = new Context();context.setVariable("id", "006");String emailContent = templateEngine.process("emailTemplate", context);mailService.sendHtmlMail("ityouknow@126.com","主題:這是模板郵件",emailContent); }當(dāng)然啦,這里要強(qiáng)調(diào)一點(diǎn)的是,我們?cè)趯?shí)現(xiàn)郵箱服務(wù)的時(shí)候,因?yàn)楦鞣N原因,總會(huì)有郵件發(fā)送失敗的情況,比如:郵件發(fā)送過于頻繁、網(wǎng)絡(luò)異常等。在出現(xiàn)這種情況的時(shí)候,我們一般會(huì)考慮重新重試發(fā)送郵件,會(huì)分為以下幾個(gè)步驟來實(shí)現(xiàn):
最后
很多時(shí)候郵件發(fā)送并不是我們主業(yè)務(wù)必須關(guān)注的結(jié)果,比如通知類、提醒類的業(yè)務(wù)可以允許延時(shí)或者失敗。這個(gè)時(shí)候可以采用異步的方式(線程)來發(fā)送郵件,加快主交易執(zhí)行速度,在實(shí)際項(xiàng)目中可以采用MQ發(fā)送郵件相關(guān)參數(shù),監(jiān)聽到消息隊(duì)列之后啟動(dòng)發(fā)送郵件。
文章轉(zhuǎn)自
與50位技術(shù)專家面對(duì)面20年技術(shù)見證,附贈(zèng)技術(shù)全景圖總結(jié)
以上是生活随笔為你收集整理的springboot集成邮箱功能的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 链计算:构建信任网络,致力无边界协同
- 下一篇: 中国市场新财富与新人群趋势