Spring 郵件發送出現bug,出現Bug以及解決方案[樂字節]

詳細Spring如何進行郵件發送

本文由樂字節Java架構課程獨家贊助播出

Spring 郵件發送

主要內容

Spring郵件發送.png

JavaMail 概述

​ JavaMail,顧名思義,提供給開發者處理電子郵件相關的編程接口。JavaMail 是由 Sun 定義的一套收發電子郵件的 API,它可以方便地執行一些常用的郵件傳輸,不同的廠商可以提供自己的實現類。但它並沒有包含在 JDK 中,而是作爲 JavaEE 的一部分。

​ 廠商所提供的 JavaMail 服務程序可以有選擇地實現某些郵件協議,常見的郵件協議包括:

  • SMTP:簡單郵件傳輸協議,用於發送電子郵件的傳輸協議;
  • POP3:用於接收電子郵件的標準協議;
  • IMAP:互聯網消息協議,是 POP3 的替代協議。

​ 這三種協議都有對應 SSL 加密傳輸的協議,分別是 SMTPS,POP3S 和 IMAPS。除 JavaMail 服務提供程序之外, JavaMail 還需要 JAF(JavaBeans Activation Framework)來處理不是純文本的郵件內容,這包括 MIME(多用途互聯網郵件擴展)、URL 頁面和文件附件等內容。另外,JavaMail 依賴 JAF(JavaBeans Activation Framework),JAF 在 Java6 之後已經合併到 JDK 中,而 JDK5 之前需要另外下載 JAF 的類庫。

協議介紹

​ 在研究 JavaMail API 的細則之前,首先需要對於 API 用到的協議有個認識。對於 java mail 來說用到的協議有常見的幾種: SMTP、POP、IMAP、MIME

SMTP

​ 簡單郵件傳輸協議(Simple Mail Transfer Protocol,SMTP)由 RFC 821 定義。它定義了發送電子郵件的機制。在 JavaMail API 環境中,您基於 JavaMail 的程序將和您的公司或因特網服務供應商的(Internet Service
Provider's,ISP's)SMTP 服務器通信。SMTP 服務器會中轉消息給接收方 SMTP 服務器以便最終讓用戶經由 POP 或 IMAP 獲得。

POP

​ POP 代表郵局協議(Post Office Protocol)。目前用的是版本 3,也稱 POP3,RFC 1939 定義了這個協議。POP 是一種機制,因特網上大多數人用它得到郵件。它規定每個用戶一個郵箱的支持。這就是它所能做的,而這也造成了許多混淆。使用 POP3 時,用戶熟悉的許多性能並不是由 POP 協議支持的,如查看有幾封新郵件消息這一性能。這些性能內建於如 Eudora 或 Microsoft Outlook 之類的程序中,它們能記住一些事,諸如最近一次收到的郵件,還能計算出有多少是新的。所以當使用 JavaMail API 時,如果您想要這類信息,您就必須自己算。

IMAP

​ IMAP 是更高級的用於接收消息的協議。在 RFC 2060 中被定義,IMAP 代表因特網消息訪問協議(Internet Message Access Protocol),目前用的是版本 4,也稱 IMAP4。在用到 IMAP 時,郵件服務器必需支持這個協議。不能僅僅把使用 POP 的程序用於 IMAP,並指望它支持 IMAP 所有性能。假設郵件服務器支持 IMAP,基於 JavaMail 的程序可以利用這種情況 — 用戶在服務器上有多個文件夾(folder),並且這些文件夾可以被多個用戶共享。因爲有這一更高級的性能,您也許會認爲所有用戶都會使用 IMAP。事實並不是這樣。要求服務器接收新消息,在用戶請求時發送到用戶手中,還要在每個用戶的多個文件夾中維護消息。這樣雖然能將消息集中備份,但隨着用戶長期的郵件夾越來越大,到磁盤空間耗盡時,每個用戶都會受到損失。使用 POP,就能卸載郵件服務器上保存的消息了。

MIME

​ MIME 代表多用途因特網郵件擴展標準(Multipurpose Internet Mail Extensions)。它不是郵件傳輸協議。但對傳輸內容的消息、附件及其它的內容定義了格式。這裏有很多不同的有效文檔:RFC 822、RFC 2045、RFC
2046 和 RFC 2047。作爲一個 JavaMail API 的用戶,您通常不必對這些格式操心。無論如何,一定存在這些格式而且程序會用到它。

JavaMail 的關鍵對象

​ JavaMail 對收發郵件進行了高級的抽象,形成了一些關鍵的的接口和類,它們構成了程序的基礎,下面我們分別來了解一下這些最常見的對象。

Properties 屬性對象

​ 由於 JavaMail 需要和郵件服務器進行通信,這就要求程序提供許多諸如服務器地址、端口、用戶名、密碼等信息,JavaMail 通過 Properties 對象封裝這些屬性信息。如下面的代碼封裝了兩個屬性信息:

Properties props = new Properties();
props.put("mail.smtp.host", "smtp.sina.com.cn");
props.put("mail.smtp.auth", "true");

​ 針對不同的的郵件協議,JavaMail 規定了服務提供者必須支持一系列屬性,下表是針對 SMTP 協議的一些常見屬性(屬性值都以 String 類型進行設置,屬性類型欄僅表示屬性是如何被解析的):

屬性名 類型 說明
mail.smtp.host String SMTP 服務器地址,如smtp.sina.com.cn
mail.smtp.port int SMTP 服務器端口號,默認爲 25
mail.smtp.auth boolean SMTP 服務器是否需要用戶認證,默認爲 false
mail.smtp.user String SMTP 默認的登陸用戶名
mail.smtp.from String 默認的郵件發送源地址
mail.smtp.socketFactory.class String socket 工廠類類名<br>通過設置該屬性可以覆蓋提供者默認的實現,必須實現javax.NET.SocketFactory接口
mail.smtp.socketFactory.port int 指定 socket 工廠類所用的端口號<br>如果沒有規定,則使用默認的端口號
mail.smtp.socketFactory.fallback boolean 設置爲 true 時,當使用指定的socket 類創建 socket 失敗後,將使用 Java.net.Socket 創建socket,默認爲 true
mail.smtp.timeout int I/O 連接超時時間,單位爲毫秒,默認爲永不超時

​ 其他幾個協議也有類似的一系列屬性,如 POP3 的 mail.pop3.host、mail.pop3.port 以及IMAP 的 mail.imap.host、mail.imap.host 等。

Session 會話對象

​ Session 是一個很容易被誤解的類,這歸咎於混淆視聽的類名。千萬不要以爲這裏的 Session 像 HttpSession 一樣代表真實的交互會話,但創建 Session 對象時,並沒有對應的物理連接,它只不過是一對配置信息的集合。

​ Session 的主要作用,包括兩個方面:

  1. 接收各種配置屬性信息:通過 Properties 對象設置的屬性信息;
  2. 初始化 JavaMail 環境:根據 JavaMail 的配置文件,初始化 JavaMail 環境,以便通過 Session 對象創建其他重要類的實例。

Transport 和 Store 傳輸和存儲

​ 郵件操作只有發送或接收兩種處理方式,JavaMail 將這兩種不同操作描述爲傳輸(javax.mail.Transport)和存儲(javax.mail.Store),傳輸對應郵件的發送,而存儲對應郵件的接收。

Message 消息對象

​ 一旦獲得 Session 對象,就可以繼續創建要發送的消息。這由 Message 類來完成。因爲 Message 是個抽象類,您必需用一個子類,多數情況下爲 javax.mail.internet.MimeMessage。MimeMessage 是個能理解 MIME 類型和頭的電子郵件消息,正如不同 RFC 中所定義的。雖然在某些頭部域非 ASCII 字符也能被譯碼,但 Message 頭只能被限制爲用 US-ASCII 字符。

Address 地址

​ 一旦您創建了 Session 和 Message,並將內容填入消息後,就可以用 Address 確定信件地址了。和 Message 一樣,Address 也是個抽象類。您用的是 javax.mail.internet.InternetAddress 類。若創建的地址只包含電子郵件地址,只要傳遞電子郵件地址到構造器就行了。

Authenticator 認證者

​ 與 java 類一樣,JavaMail API 也可以利用 Authenticator 通過用戶名和密碼訪問受保護的資源。對於 JavaMail API 來說,這些資源就是郵件服務器。JavaMail Authenticator 在 javax.mail 包中,而且它和 java.net 中同名的類 Authenticator 不同。兩者並不共享同一個 Authenticator,因爲 JavaMail API 用於 Java 1.1,它沒有 java.net 類別。要使用 Authenticator,先創建一個抽象類的子類,並從 getPasswordAuthentication() 方法中返回 PasswordAuthentication 實例。創建完成後,您必需向 session 註冊 Authenticator。然後,在需要認證的時候,就會通知 Authenticator。您可以彈出窗口,也可以從配置文件中(雖然沒有加密是不安全的)讀取用戶名和密碼,將它們作爲 PasswordAuthentication 對象返回給調用程序。

Java Mail 環境準備

設置郵箱服務

這裏是以163郵箱爲例

![]()

註冊 163 郵箱,登錄 163 郵箱後,設置郵箱賬戶開通 smtp 服務

![]()

![]()

​ 需要根據註冊時的手機號發送的驗證碼來開通獲取郵箱客戶端授權碼。開通成功後,會顯示個人授權訪問碼,該授權碼是後面通過 Java mail 發送郵件的認證密碼,非常重要。

添加依賴

創建 Maven 項目,在 pom.xml 配置文件中添加 mail 的所需的依賴

<!-- Java Mail -->
<dependency>
    <groupId>com.sun.mail</groupId>
    <artifactId>javax.mail</artifactId>
    <version>1.6.2</version>
</dependency>
<dependency>
    <groupId>javax.mail</groupId>
    <artifactId>javax.mail-api</artifactId>
    <version>1.6.2</version>
</dependency>

ependency>
<groupId>javax.mail</groupId>
<artifactId>javax.mail-api</artifactId>
<version>1.6.2</version>
</dependency>



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