SpringBoot中發送QQ郵件

本文是vhr系列的第十二篇,項目地址https://github.com/lenve/vhr html

郵件發送也是一個老生常談的問題了,代碼雖然簡單,可是許多小夥伴對過程不太理解,因此仍是打算和各位小夥伴聊聊這個話題。java

郵件協議

咱們常常會聽到各類各樣的郵件協議,好比SMTP、POP三、IMAP,那麼這些協議有什麼做用,有什麼區別?咱們先來討論一下這個問題。 ios

SMTP是一個基於TCP/IP的應用層協議,江湖地位有點相似於HTTP,SMTP服務器默認監聽的端口號爲25。看到這裏,小夥伴們可能會想到既然SMTP協議是基於TCP/IP的應用層協議,那麼我是否是也能夠經過Socket發送一封郵件呢?回答是確定的。 git

生活中咱們投遞一封郵件要通過以下幾個步驟: github

1.深圳的小王先將郵件投遞到深圳的郵局
2.深圳的郵局將郵件運送到上海的郵局
3.上海的小張來郵局取郵件 數據庫

這是一個縮減版的生活中郵件發送過程。這三個步驟能夠分別對應咱們的郵件發送過程,假設從aaa@qq.com發送郵件到111@163.com: 編程

1.aaa@qq.com先將郵件投遞到騰訊的郵件服務器
2.騰訊的郵件服務器將咱們的郵件投遞到網易的郵件服務器
3.111@163.com登陸網易的郵件服務器查看郵件 axios

郵件投遞大體就是這個過程,這個過程就涉及到了多個協議,咱們來分別看一下。 後端

SMTP協議全稱爲Simple Mail Transfer Protocol,譯做簡單郵件傳輸協議,它定義了郵件客戶端軟件於SMTP服務器之間,以及SMTP服務器與SMTP服務器之間的通訊規則。也就是說aaa@qq.com用戶先將郵件投遞到騰訊的SMTP服務器這個過程就使用了SMTP協議,而後騰訊的SMTP服務器將郵件投遞到網易的SMTP服務器這個過程也依然使用了SMTP協議,SMTP服務器就是用來收郵件。而POP3協議全稱爲Post Office Protocol,譯做郵局協議,它定義了郵件客戶端與POP3服務器之間的通訊規則,那麼該協議在什麼場景下會用到呢?當郵件到達網易的SMTP服務器以後,111@163.com用戶須要登陸服務器查看郵件,這個時候就該協議就用上了:郵件服務商都會爲每個用戶提供專門的郵件存儲空間,SMTP服務器收到郵件以後,就將郵件保存到相應用戶的郵件存儲空間中,若是用戶要讀取郵件,就須要經過郵件服務商的POP3郵件服務器來完成。最後,可能也有小夥伴們據說過IMAP協議,這個協議是對POP3協議的擴展,功能更強,做用相似,這裏再也不贅述。服務器

發送QQ郵件準備工做

首先咱們須要先登陸QQ郵箱網頁版,點擊上方的設置按鈕:

圖片描述

而後點擊帳戶選項卡:

圖片描述

在帳戶選項卡中找到開啓POP3/SMTP選項,以下:

圖片描述

點擊開啓,開啓相關功能,開啓過程須要手機號碼驗證,按照步驟操做便可,不贅述。開啓成功以後,便可獲取一個受權碼,將該號碼保存好,一會使用。

而後咱們須要JavaxMail這個jar包,小夥伴能夠直接去Maven中央倉庫下載,這裏再也不贅述。

發送

簡單郵件

若是咱們只發送一個簡單的文本,發送方式就比較簡單,整個過程能夠分爲三步以下:

第一步:構造SMTP郵件服務器的基本環境

Properties properties = new Properties();
properties.setProperty("mail.host", "smtp.qq.com");
properties.setProperty("mail.transport.protocol", "smtp");
properties.setProperty("mail.smtp.auth", "true");
properties.setProperty("mail.smtp.socketFactory.class", "javax.net.ssl.SSLSocketFactory");
properties.setProperty("mail.smtp.port", "465");
Session session = Session.getDefaultInstance(properties);
session.setDebug(true);

第二步:構造郵件

MimeMessage mimeMessage = new MimeMessage(session);
mimeMessage.addRecipients(Message.RecipientType.TO, "111@qq.com");//設置收信人
mimeMessage.addRecipients(Message.RecipientType.CC, "222@qq.com");//抄送
mimeMessage.setFrom("1510161612@qq.com");//郵件發送人
mimeMessage.setSubject("測試郵件主題");//郵件主題
mimeMessage.setContent("Hello,這是一封測試郵件", "text/html;charset=utf-8");//正文

第三步:發送郵件

Transport transport = session.getTransport();
transport.connect("smtp.qq.com", "333@qq.com", "剛剛申請到的受權碼");
transport.sendMessage(mimeMessage, mimeMessage.getAllRecipients());//發送郵件,第二個參數爲收件人
transport.close();

複雜郵件

發送複雜郵件,第一步和第三步也是同樣的,只有第二步構造郵件的過程比較麻煩,那麼接下來給小夥伴們演示一個發送一封圖文+兩個附件的郵件。要發送複雜郵件,得先熟悉三個概念,以下:

1.MimeMessage:該類是個能理解MIME類型和頭的電子郵件消息
2.MimeMultipart:該類定義了增長、刪除以及獲取郵件不一樣部份內容的方法
3.MimeBodyPart:該對象表明一個MimeMessage對象內容的一部分。每一個MimeBodyPart被認爲有兩部分:MIME類型和匹配這個類型的內容

完整的郵件生成過程以下(第一步和第三步參考上文):

MimeMessage mimeMessage = new MimeMessage(session);
mimeMessage.addRecipients(Message.RecipientType.TO, "111@qq.com");//設置收信人
mimeMessage.addRecipients(Message.RecipientType.CC, "222@qq.com");//抄送
mimeMessage.setFrom("333@qq.com");//郵件發送人
mimeMessage.setSubject("測試郵件主題");//郵件主題

MimeMultipart mixed = new MimeMultipart("mixed");
mimeMessage.setContent(mixed);//設置整封郵件的MIME消息體爲混合的組合關係

MimeBodyPart attach1 = new MimeBodyPart();//建立附件1
MimeBodyPart attach2 = new MimeBodyPart();//建立附件2
MimeBodyPart content = new MimeBodyPart();//建立郵件正文

mixed.addBodyPart(attach1);//將附件一添加到MIME消息體中
mixed.addBodyPart(attach2);//將附件二添加到MIME消息體中
mixed.addBodyPart(content);//將正文添加到消息體中

FileDataSource fds1 = new FileDataSource(new File("C:\\Users\\sang\\Desktop\\1.png"));//構造附件一的數據源
DataHandler dh1 = new DataHandler(fds1);//數據處理
attach1.setDataHandler(dh1);//設置附件一的數據源
attach1.setFileName("1.png");//設置附件一的文件名

//附件二的操做與附件一相似,這裏就不一一註釋了
FileDataSource fds2 = new FileDataSource(new File("C:\\Users\\sang\\Desktop\\博客筆記.xlsx"));
DataHandler dh2 = new DataHandler(fds2);
attach2.setDataHandler(dh2);
attach2.setFileName(MimeUtility.encodeText("博客筆記.xlsx"));//設置文件名時,若是有中文,能夠經過MimeUtility類中的encodeText方法進行編碼,避免亂碼

MimeMultipart bodyMimeMultipart = new MimeMultipart("related");//設置正文的MIME類型
content.setContent(bodyMimeMultipart);//將bodyMimeMultipart添加到正文消息體中

MimeBodyPart bodyPart = new MimeBodyPart();//正文的HTML部分
bodyPart.setContent("<h1>Hello你們好,這是一封測試郵件<img src='cid:2.png'/></h1>","text/html;charset=utf-8");

MimeBodyPart picPart = new MimeBodyPart();//正文的圖片部分
DataHandler dataHandler = new DataHandler(new FileDataSource("C:\\Users\\sang\\Desktop\\2.png"));
picPart.setDataHandler(dataHandler);
picPart.setContentID("2.png");

//將正文的HTML和圖片部分分別添加到bodyMimeMultipart中
bodyMimeMultipart.addBodyPart(bodyPart);
bodyMimeMultipart.addBodyPart(picPart);

mimeMessage.saveChanges();

OK,Java Mail發送QQ郵件就是這麼簡單,至於其餘的如163,sina等,寫法相似,這裏我就不贅述了。

小夥伴可能也注意到了,複雜郵件的構造其實有點麻煩,在項目中,咱們可使用Freemarker來構建郵件模板,這個模板問題咱們下篇文章介紹。

本系列其餘文章:

1.SpringBoot+Vue先後端分離,使用SpringSecurity完美處理權限問題(一)
2.SpringBoot+Vue先後端分離,使用SpringSecurity完美處理權限問題(二)
3.SpringSecurity中密碼加鹽與SpringBoot中異常統一處理
4.axios請求封裝和異常統一處理
5.權限管理模塊中動態加載Vue組件
6.SpringBoot+Vue先後端分離,使用SpringSecurity完美處理權限問題(六)
7.vhr部門管理數據庫設計與編程
8.使用MyBatis輕鬆實現遞歸查詢與存儲過程調用
9.ElementUI中tree控件踩坑記
10.SpringBoot中自定義參數綁定
11.SpringBoot中使用POI,快速實現Excel導入導出

關注公衆號,能夠及時接收到最新文章:
圖片描述

相關文章
相關標籤/搜索