Spring 郵件發(fā)送
主要內容
JavaMail 概述
? JavaMail纤控,顧名思義欢瞪,提供給開發(fā)者處理電子郵件相關的編程接口活烙。JavaMail 是由 Sun 定義的一套收發(fā)電子郵件的 API,它可以方便地執(zhí)行一些常用的郵件傳輸遣鼓,不同的廠商可以提供自己的實現類啸盏。但它并沒有包含在 JDK 中,而是作為 JavaEE 的一部分骑祟。
? 廠商所提供的 JavaMail 服務程序可以有選擇地實現某些郵件協議回懦,常見的郵件協議包括:
- SMTP:簡單郵件傳輸協議,用于發(fā)送電子郵件的傳輸協議次企;
- 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 定義。它定義了發(fā)送電子郵件的機制嗦玖。在 JavaMail API 環(huán)境中患雇,您基于 JavaMail 的程序將和您的公司或因特網服務供應商的(Internet Service
Provider's,ISP's)SMTP 服務器通信宇挫。SMTP 服務器會中轉消息給接收方 SMTP 服務器以便最終讓用戶經由 POP 或 IMAP 獲得苛吱。
POP
? POP 代表郵局協議(Post Office Protocol)。目前用的是版本 3器瘪,也稱 POP3翠储,RFC 1939 定義了這個協議。POP 是一種機制橡疼,因特網上大多數人用它得到郵件援所。它規(guī)定每個用戶一個郵箱的支持。這就是它所能做的欣除,而這也造成了許多混淆住拭。使用 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灰追。事實并不是這樣堵幽。要求服務器接收新消息,在用戶請求時發(fā)送到用戶手中弹澎,還要在每個用戶的多個文件夾中維護消息朴下。這樣雖然能將消息集中備份,但隨著用戶長期的郵件夾越來越大苦蒿,到磁盤空間耗盡時殴胧,每個用戶都會受到損失。使用 POP佩迟,就能卸載郵件服務器上保存的消息了团滥。
MIME
? MIME 代表多用途因特網郵件擴展標準(Multipurpose Internet Mail Extensions)。它不是郵件傳輸協議报强。但對傳輸內容的消息惫撰、附件及其它的內容定義了格式。這里有很多不同的有效文檔:RFC 822躺涝、RFC 2045、RFC
2046 和 RFC 2047扼雏。作為一個 JavaMail API 的用戶坚嗜,您通常不必對這些格式操心。無論如何诗充,一定存在這些格式而且程序會用到它苍蔬。
JavaMail 的關鍵對象
? JavaMail 對收發(fā)郵件進行了高級的抽象,形成了一些關鍵的的接口和類蝴蜓,它們構成了程序的基礎碟绑,下面我們分別來了解一下這些最常見的對象俺猿。
Properties 屬性對象
? 由于 JavaMail 需要和郵件服務器進行通信,這就要求程序提供許多諸如服務器地址格仲、端口押袍、用戶名、密碼等信息凯肋,JavaMail 通過 Properties 對象封裝這些屬性信息谊惭。如下面的代碼封裝了兩個屬性信息:
Properties props = new Properties();
props.put("mail.smtp.host", "smtp.sina.com.cn");
props.put("mail.smtp.auth", "true");
? 針對不同的的郵件協議,JavaMail 規(guī)定了服務提供者必須支持一系列屬性侮东,下表是針對 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 | 默認的郵件發(fā)送源地址 |
mail.smtp.socketFactory.class | String | socket 工廠類類名 通過設置該屬性可以覆蓋提供者默認的實現,必須實現javax.NET.SocketFactory接口 |
mail.smtp.socketFactory.port | int | 指定 socket 工廠類所用的端口號 如果沒有規(guī)定宽闲,則使用默認的端口號 |
mail.smtp.socketFactory.fallback | boolean | 設置為 true 時众眨,當使用指定的socket 類創(chuàng)建 socket 失敗后,將使用 Java.net.Socket 創(chuàng)建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 一樣代表真實的交互會話友雳,但創(chuàng)建 Session 對象時稿湿,并沒有對應的物理連接,它只不過是一對配置信息的集合押赊。
? Session 的主要作用饺藤,包括兩個方面:
- 接收各種配置屬性信息:通過 Properties 對象設置的屬性信息;
- 初始化 JavaMail 環(huán)境:根據 JavaMail 的配置文件流礁,初始化 JavaMail 環(huán)境涕俗,以便通過 Session 對象創(chuàng)建其他重要類的實例。
Transport 和 Store 傳輸和存儲
? 郵件操作只有發(fā)送或接收兩種處理方式神帅,JavaMail 將這兩種不同操作描述為傳輸(javax.mail.Transport)和存儲(javax.mail.Store)再姑,傳輸對應郵件的發(fā)送,而存儲對應郵件的接收找御。
Message 消息對象
? 一旦獲得 Session 對象元镀,就可以繼續(xù)創(chuàng)建要發(fā)送的消息绍填。這由 Message 類來完成。因為 Message 是個抽象類栖疑,您必需用一個子類讨永,多數情況下為 javax.mail.internet.MimeMessage。MimeMessage 是個能理解 MIME 類型和頭的電子郵件消息蔽挠,正如不同 RFC 中所定義的住闯。雖然在某些頭部域非 ASCII 字符也能被譯碼,但 Message 頭只能被限制為用 US-ASCII 字符澳淑。
Address 地址
? 一旦您創(chuàng)建了 Session 和 Message比原,并將內容填入消息后,就可以用 Address 確定信件地址了杠巡。和 Message 一樣量窘,Address 也是個抽象類。您用的是 javax.mail.internet.InternetAddress 類氢拥。若創(chuàng)建的地址只包含電子郵件地址蚌铜,只要傳遞電子郵件地址到構造器就行了。
Authenticator 認證者
? 與 java 類一樣嫩海,JavaMail API 也可以利用 Authenticator 通過用戶名和密碼訪問受保護的資源冬殃。對于 JavaMail API 來說,這些資源就是郵件服務器叁怪。JavaMail Authenticator 在 javax.mail 包中审葬,而且它和 java.net 中同名的類 Authenticator 不同。兩者并不共享同一個 Authenticator奕谭,因為 JavaMail API 用于 Java 1.1涣觉,它沒有 java.net 類別。要使用 Authenticator血柳,先創(chuàng)建一個抽象類的子類官册,并從 getPasswordAuthentication() 方法中返回 PasswordAuthentication 實例。創(chuàng)建完成后难捌,您必需向 session 注冊 Authenticator膝宁。然后,在需要認證的時候根吁,就會通知 Authenticator昆汹。您可以彈出窗口,也可以從配置文件中(雖然沒有加密是不安全的)讀取用戶名和密碼婴栽,將它們作為 PasswordAuthentication 對象返回給調用程序。
Java Mail 環(huán)境準備
設置郵箱服務
這里是以163郵箱為例
[外鏈圖片轉存失敗,源站可能有防盜鏈機制,建議將圖片保存下來直接上傳(img-OYChfhWu-1607915338270)(/mail-02.png)]
注冊 163 郵箱辈末,登錄 163 郵箱后愚争,設置郵箱賬戶開通 smtp 服務
[外鏈圖片轉存失敗,源站可能有防盜鏈機制,建議將圖片保存下來直接上傳(img-Efjzgo4T-1607915338273)(/mail-03.png)]
[外鏈圖片轉存失敗,源站可能有防盜鏈機制,建議將圖片保存下來直接上傳(img-Tc8dkcZH-1607915338278)(/mail-04.png)]
? 需要根據注冊時的手機號發(fā)送的驗證碼來開通獲取郵箱客戶端授權碼映皆。開通成功后,會顯示個人授權訪問碼轰枝,該授權碼是后面通過 Java mail 發(fā)送郵件的認證密碼捅彻,非常重要。
添加依賴
創(chuàng)建 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>
Java Mail 發(fā)送郵件
發(fā)送普通文本的郵件
package com.xxxx.mail;
import javax.activation.DataHandler;
import javax.activation.FileDataSource;
import javax.mail.*;
import javax.mail.internet.*;
import java.io.UnsupportedEncodingException;
import java.util.Date;
import java.util.Properties;
/**
* 發(fā)送普通文本的郵件
*/
public class MailTest01 {
public static void main(String[] args) throws Exception {
// 定義郵箱服務器配置
Properties prop = new Properties();
// 設置郵件服務器主機名 (163 郵件服務器地址:"mail.smtp.host" "smtp.163.com")
prop.setProperty("mail.smtp.host", "smtp.163.com");
// 設置郵件服務器的端口
prop.setProperty("mail.smtp.port", "25");
// 設置郵件服務器認證屬性 (設置為true表示發(fā)送服務器需要身份驗證)
prop.setProperty("mail.smtp.auth", "true");
// 某些郵箱服務器要求 SMTP 連接需要使用 SSL 安全認證
// prop.setProperty("mail.smtp.port", "465");
// prop.setProperty("mail.smtp.socketFactory.class", "javax.net.ssl.SSLSocketFactory");
// prop.setProperty("mail.smtp.socketFactory.fallback", "false");
// prop.setProperty("mail.smtp.socketFactory.port", "465");
// 使用JavaMail發(fā)送郵件的5個步驟
// 1. 創(chuàng)建session
Session session = Session.getInstance(prop);
// 開啟Session的debug模式步淹,這樣就可以查看到程序發(fā)送Email的運行狀態(tài)
session.setDebug(true);
// 2. 通過session得到transport對象
Transport ts = session.getTransport();
// 3. 使用郵箱的用戶名和密碼連上郵件服務器(用戶名只需寫@前面的即可,密碼是指授權碼)
ts.connect("smtp.163.com", "用戶名", "密碼");
// 4. 創(chuàng)建郵件
// 發(fā)送普通文本的郵件
Message message = createSimpleTxtMail(session);
// 5. 發(fā)送郵件
ts.sendMessage(message, message.getAllRecipients());
// 關閉transport對象
ts.close();
}
/**
* 普通文本郵件
* 創(chuàng)建一封只包含文本的郵件
* @param session
* @return
*/
public static MimeMessage createSimpleTxtMail(Session session) throws MessagingException {
// 創(chuàng)建郵件對象
MimeMessage message = new MimeMessage(session);
// 設置郵件的發(fā)件人的郵箱地址
message.setFrom(new InternetAddress("發(fā)件人的郵箱地址"));
// 設置郵件的收件人的郵箱地址 (現在發(fā)件人和收件人是一樣的,那就是自己給自己發(fā))
message.setRecipient(Message.RecipientType.TO, new InternetAddress("收件人的郵箱地址"));
// 發(fā)送給多個收件人
// message.setRecipients(Message.RecipientType.TO, new InternetAddress[] {});
// Cc: 抄送(可選)
// message.setRecipient(MimeMessage.RecipientType.CC, new InternetAddress(""));
// Bcc: 密送(可選)
// message.setRecipient(MimeMessage.RecipientType.BCC, new InternetAddress(""));
// 郵件的主題
message.setSubject("測試文本郵件");
// 設置發(fā)送日期
message.setSentDate(new Date());
// 郵件的文本內容 (setText():純文本內容)
message.setText("你好,這是一封測試郵件中狂!");
// 返回創(chuàng)建好的郵件對象
return message;
}
}
效果如下:
[外鏈圖片轉存失敗,源站可能有防盜鏈機制,建議將圖片保存下來直接上傳(img-48AWqKi4-1607915338282)(/mail-05.png)]
發(fā)送HTML內容的郵件
package com.xxxx.mail;
import javax.activation.DataHandler;
import javax.activation.FileDataSource;
import javax.mail.Message;
import javax.mail.MessagingException;
import javax.mail.Session;
import javax.mail.Transport;
import javax.mail.internet.InternetAddress;
import javax.mail.internet.MimeBodyPart;
import javax.mail.internet.MimeMessage;
import javax.mail.internet.MimeMultipart;
import java.util.Date;
import java.util.Properties;
/**
* 發(fā)送HTML內容的郵件
*/
public class MailTest02 {
public static void main(String[] args) throws Exception {
// 定義郵箱服務器配置
Properties prop = new Properties();
// 設置郵件服務器主機名 (163 郵件服務器地址:"mail.smtp.host" "smtp.163.com")
prop.setProperty("mail.smtp.host", "smtp.163.com");
// 設置郵件服務器的端口
prop.setProperty("mail.smtp.port", "25");
// 設置郵件服務器認證屬性 (設置為true表示發(fā)送服務器需要身份驗證)
prop.setProperty("mail.smtp.auth", "true");
// 使用JavaMail發(fā)送郵件的5個步驟
// 1. 創(chuàng)建session
Session session = Session.getInstance(prop);
// 開啟Session的debug模式弃锐,這樣就可以查看到程序發(fā)送Email的運行狀態(tài)
session.setDebug(true);
// 2. 通過session得到transport對象
Transport ts = session.getTransport();
// 3. 使用郵箱的用戶名和密碼連上郵件服務器(用戶名只需寫@前面的即可,密碼是指授權碼)
ts.connect("smtp.163.com", "用戶名", "密碼");
// 4. 創(chuàng)建郵件
// 發(fā)送HTML內容的郵件
Message message = createHtmlMail(session);
// 5. 發(fā)送郵件
ts.sendMessage(message, message.getAllRecipients());
// 關閉transport對象
ts.close();
}
/**
* HTML內容郵件
* 創(chuàng)建一封包含html內容的郵件
*/
public static MimeMessage createHtmlMail(Session session) throws Exception {
// 創(chuàng)建郵件對象
MimeMessage message = new MimeMessage(session);
// 設置郵件的發(fā)件人的郵箱地址
message.setFrom(new InternetAddress("發(fā)件人的郵箱地址"));
// 設置郵件的收件人的郵箱地址 (現在發(fā)件人和收件人是一樣的蒙兰,那就是自己給自己發(fā))
message.setRecipient(Message.RecipientType.TO, new InternetAddress("收件人的郵箱地址"));
// 郵件的主題
message.setSubject("測試HTML郵件");
// 設置發(fā)送日期
message.setSentDate(new Date());
// 準備郵件數據
/**
* Message表示一個郵件,messgaes.getContent()返回一個Multipart對象。
* 一個Multipart對象包含一個或多個BodyPart對象缝其,來組成郵件的正文部分(包括附件)。
*/
// 創(chuàng)建多媒體對象
MimeMultipart multipart = new MimeMultipart();
// 創(chuàng)建郵件體對象
MimeBodyPart bodyPart = new MimeBodyPart();
// 設置HTML內容
StringBuffer sb = new StringBuffer();
sb.append("<html><body><a );
bodyPart.setContent(sb.toString(), "text/html;charset=UTF-8");
// 將bodyPart對象設置到multipart對象中
multipart.addBodyPart(bodyPart);
// 將multipart對象設置到message對象中 (setContent():)
message.setContent(multipart);
// 返回創(chuàng)建好的郵件對象
return message;
}
}
效果如下:
[外鏈圖片轉存失敗,源站可能有防盜鏈機制,建議將圖片保存下來直接上傳(img-A6auqgwb-1607915338284)(/mail-06.png)]
發(fā)送包含附件的郵件
package com.xxxx.mail;
import javax.activation.DataHandler;
import javax.activation.FileDataSource;
import javax.mail.Message;
import javax.mail.MessagingException;
import javax.mail.Session;
import javax.mail.Transport;
import javax.mail.internet.InternetAddress;
import javax.mail.internet.MimeBodyPart;
import javax.mail.internet.MimeMessage;
import javax.mail.internet.MimeMultipart;
import java.util.Date;
import java.util.Properties;
/**
* 發(fā)送包含附件的郵件
*/
public class MailTest03 {
public static void main(String[] args) throws Exception {
// 定義郵箱服務器配置
Properties prop = new Properties();
// 設置郵件服務器主機名 (163 郵件服務器地址:"mail.smtp.host" "smtp.163.com")
prop.setProperty("mail.smtp.host", "smtp.163.com");
// 設置郵件服務器的端口
prop.setProperty("mail.smtp.port", "25");
// 設置郵件服務器認證屬性 (設置為true表示發(fā)送服務器需要身份驗證)
prop.setProperty("mail.smtp.auth", "true");
// 使用JavaMail發(fā)送郵件的5個步驟
// 1. 創(chuàng)建session
Session session = Session.getInstance(prop);
// 開啟Session的debug模式徘六,這樣就可以查看到程序發(fā)送Email的運行狀態(tài)
session.setDebug(true);
// 2. 通過session得到transport對象
Transport ts = session.getTransport();
// 3. 使用郵箱的用戶名和密碼連上郵件服務器(用戶名只需寫@前面的即可内边,密碼是指授權碼)
ts.connect("smtp.163.com", "用戶名", "密碼");
// 4. 創(chuàng)建郵件
// 發(fā)送包含附件的郵件
Message message = createAttachMail(session);
// 5. 發(fā)送郵件
ts.sendMessage(message, message.getAllRecipients());
// 關閉transport對象
ts.close();
}
/**
* 包含附件的郵件
* 創(chuàng)建一封包含附件的郵件
* @param session
* @return
* @throws MessagingException
*/
public static MimeMessage createAttachMail(Session session) throws MessagingException {
// 創(chuàng)建郵件對象
MimeMessage message = new MimeMessage(session);
// 設置郵件的發(fā)件人的郵箱地址
message.setFrom(new InternetAddress("發(fā)件人的郵箱地址"));
// 設置郵件的收件人的郵箱地址 (現在發(fā)件人和收件人是一樣的,那就是自己給自己發(fā))
message.setRecipient(Message.RecipientType.TO, new InternetAddress("收件人的郵箱地址"));
// 郵件的主題
message.setSubject("測試包含附件的郵件");
// 設置發(fā)送日期
message.setSentDate(new Date());
// 創(chuàng)建郵件正文
MimeBodyPart bodyPart = new MimeBodyPart();
bodyPart.setContent("使用JavaMail創(chuàng)建的帶附件的郵件", "text/html;charset=UTF-8");
// 創(chuàng)建附件
MimeBodyPart attachPart = new MimeBodyPart();
// 本地文件
DataHandler dh = new DataHandler(new FileDataSource("C:\\work\\郵件附件.txt"));
attachPart.setDataHandler(dh);
// 附件名
attachPart.setFileName(dh.getName());
// 創(chuàng)建容器描述數據關系
MimeMultipart multipart = new MimeMultipart();
// 添加正文
multipart.addBodyPart(bodyPart);
// 添加附件
multipart.addBodyPart(attachPart);
// 如果在郵件中要添加附件待锈,設置為mixed漠其;。
multipart.setSubType("mixed");
// 設置郵件的內容
message.setContent(multipart);
// 返回創(chuàng)建好的郵件對象
return message;
}
}
效果如下:
[外鏈圖片轉存失敗,源站可能有防盜鏈機制,建議將圖片保存下來直接上傳(img-8xFx9IR8-1607915338286)(/mail-07.png)]
Java Mail 郵件發(fā)送封裝
創(chuàng)建郵件發(fā)送信息類
package com.xxxx.mail;
import java.util.List;
/**
* 郵件發(fā)送信息類
* 定義發(fā)送郵件時 郵件服務器 端口 發(fā)送方用戶名 密碼等字段
*/
public class MailSendInfo {
private String serverHost; // 服務器主機
private String serverPort; // 服務器端口
private String fromAddress;// 發(fā)送方郵箱地址
private List<String> toAddress; // 接收方郵箱地址
private String userName; // 郵件服務器用戶名
private String userPwd; // 郵件服務器密碼(授權密碼)
private String subject; // 郵件主題
private String content; // 郵件內容
private Boolean flag = true; // 是否需要身份認證
private List<String> attachFileNames; // 附件文件名
public Boolean getFlag() {
return flag;
}
public void setFlag(Boolean flag) {
this.flag = flag;
}
public String getServerHost() {
return serverHost;
}
public void setServerHost(String serverHost) {
this.serverHost = serverHost;
}
public String getServerPort() {
return serverPort;
}
public void setServerPort(String serverPort) {
this.serverPort = serverPort;
}
public String getFromAddress() {
return fromAddress;
}
public void setFromAddress(String fromAddress) {
this.fromAddress = fromAddress;
}
public List<String> getToAddress() {
return toAddress;
}
public void setToAddress(List<String> toAddress) {
this.toAddress = toAddress;
}
public String getUserName() {
return userName;
}
public void setUserName(String userName) {
this.userName = userName;
}
public String getUserPwd() {
return userPwd;
}
public void setUserPwd(String userPwd) {
this.userPwd = userPwd;
}
public String getSubject() {
return subject;
}
public void setSubject(String subject) {
this.subject = subject;
}
public String getContent() {
return content;
}
public void setContent(String content) {
this.content = content;
}
public List<String> getAttachFileNames() {
return attachFileNames;
}
public void setAttachFileNames(List<String> attachFileNames) {
this.attachFileNames = attachFileNames;
}
}
創(chuàng)建認證類
package com.xxxx.mail;
import javax.mail.Authenticator;
import javax.mail.PasswordAuthentication;
/**
* 認證類
*/
public class MyAuthenticator extends Authenticator {
private String userName; // 郵箱
private String userPwd; // 密碼(授權碼)
public MyAuthenticator(String userName, String userPwd) {
this.userName = userName;
this.userPwd = userPwd;
}
/**
* 郵件服務器發(fā)送郵件時炉擅,進行身份驗證
* @return
*/
@Override
protected PasswordAuthentication getPasswordAuthentication() {
return new PasswordAuthentication(userName, userPwd);
}
}
創(chuàng)建郵件發(fā)送器
package com.xxxx.mail;
import javax.activation.DataHandler;
import javax.activation.FileDataSource;
import javax.mail.*;
import javax.mail.internet.*;
import java.io.File;
import java.util.Date;
import java.util.List;
import java.util.Properties;
public class MailSender {
public void sendMail(MailSendInfo mailSendInfo){
Message message = null;
Session session = null;
try {
// 定義郵箱服務器配置
Properties props = new Properties();
// 163 郵件服務器地址
props.put("mail.smtp.host", mailSendInfo.getServerHost());
// 163 郵件服務器端口
props.put("mail.smtp.port",mailSendInfo.getServerPort());
// 163 郵件服務器認證屬性
props.put("mail.smtp.auth", mailSendInfo.getFlag());
// 身份認證類
MyAuthenticator authenticator = new MyAuthenticator(mailSendInfo.getUserName(), mailSendInfo.getUserPwd());
// 創(chuàng)建session
session = Session.getDefaultInstance(props, authenticator);
// 開啟Session的debug模式辉懒,這樣就可以查看到程序發(fā)送Email的運行狀態(tài)
session.setDebug(true);
// 創(chuàng)建message郵件對象
message = new MimeMessage(session);
// 設置發(fā)送方的郵箱地址
Address from = new InternetAddress(mailSendInfo.getFromAddress());
message.setFrom(from);
// 設置發(fā)送時間
message.setSentDate(new Date());
// 判斷接收方的郵箱地址
if(null != mailSendInfo.getToAddress() && mailSendInfo.getToAddress().size() > 0){
// 定義數組
Address[] addresses = new Address[mailSendInfo.getToAddress().size()];
// 循環(huán)獲取接收方的郵箱地址,并設置到對應的address數組中
for(int i = 0; i < mailSendInfo.getToAddress().size(); i++){
Address address = new InternetAddress(mailSendInfo.getToAddress().get(i));
addresses[i] = address;
}
// 設置接收方的郵箱地址
message.setRecipients(Message.RecipientType.TO, addresses);
// 設置郵件主題
message.setSubject(mailSendInfo.getSubject());
// 創(chuàng)建多媒體對象容器
Multipart multipart = new MimeMultipart();
// 創(chuàng)建正文內容
BodyPart bodyPart =new MimeBodyPart();
bodyPart.setContent(mailSendInfo.getContent(),"text/html;charset=utf-8");
// 添加正文 (將正文內容設置到多媒體對象容器中)
multipart.addBodyPart(bodyPart);
// 獲取所有的附件內容
List<String> files = mailSendInfo.getAttachFileNames();
// 判斷是否包含附件內容
if(null != files && files.size() > 0){
for(int i = 0; i < files.size(); i++){
// 獲取對應的附件對象
File tempFile = new File(files.get(i));
// 判斷附件是否存在
if(tempFile.exists()){
// 如果附件存在谍失,創(chuàng)建附件對象
BodyPart attachPart = new MimeBodyPart();
attachPart.setDataHandler(new DataHandler(new FileDataSource(tempFile)));
// 設置文件名 (解決附件名亂碼)
attachPart.setFileName(MimeUtility.encodeText(tempFile.getName()));
// 添加附件 (將附件內容添加到多媒體對象容器中)
multipart.addBodyPart(attachPart);
}
}
}
// 設置郵件內容
message.setContent(multipart);
// 發(fā)送郵件
Transport.send(message);
}
} catch (Exception e) {
e.printStackTrace();
}
}
}
郵件發(fā)送測試
發(fā)送HTML內容的郵件
/**
* 發(fā)送HTML內容的郵件
*/
public static void testHtmlMail() {
MailSendInfo mailSendInfo = new MailSendInfo();
mailSendInfo.setServerHost("smtp.163.com");
mailSendInfo.setServerPort("25");
mailSendInfo.setUserName("郵箱用戶名");
mailSendInfo.setUserPwd("密碼(授權碼)");
mailSendInfo.setSubject("郵件封裝");
mailSendInfo.setFromAddress("發(fā)件人的郵箱地址");
mailSendInfo.setContent("<h2>這是封裝后發(fā)送的郵件</h2>");
List<String> users = new ArrayList<>();
users.add("收件人的郵箱地址");
mailSendInfo.setToAddress(users);
MailSender mailSender=new MailSender();
mailSender.sendMail(mailSendInfo);
}
效果如下:
[外鏈圖片轉存失敗,源站可能有防盜鏈機制,建議將圖片保存下來直接上傳(img-UDUgii3O-1607915338289)(/mail-08.png)]
發(fā)送包含附件的郵件
/**
* 發(fā)送包含附件的郵件
*/
public static void testAttachMail() {
MailSendInfo mailSendInfo = new MailSendInfo();
mailSendInfo.setServerHost("smtp.163.com");
mailSendInfo.setServerPort("25");
mailSendInfo.setUserName("用戶名");
mailSendInfo.setUserPwd("密碼(授權碼)");
mailSendInfo.setSubject("郵件封裝");
mailSendInfo.setFromAddress("發(fā)件人的郵箱地址");
mailSendInfo.setContent("<h2>包含附件的郵件</h2>");
List<String> users = new ArrayList<>();
users.add("收件人的郵箱地址");
mailSendInfo.setToAddress(users);
// 添加附件
List<String> files=new ArrayList<String>();
files.add("C:\\work\\郵件附件.txt");
files.add("C:\\work\\名單.xlsx");
mailSendInfo.setAttachFileNames(files);
MailSender mailSender=new MailSender();
mailSender.sendMail(mailSendInfo);
}
效果如下:
[外鏈圖片轉存失敗,源站可能有防盜鏈機制,建議將圖片保存下來直接上傳(img-l9NKzd5z-1607915338291)(/mail-09.png)]
使用 Spring API 實現郵件發(fā)送
環(huán)境準備
創(chuàng)建 Maven 項目眶俩,在 pom.xml 文件中添加依賴
<!-- spring核心 jar 依賴 -->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context</artifactId>
<version>5.2.4.RELEASE</version>
</dependency>
<!--spring 上下文環(huán)境 支持-->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context-support</artifactId>
<version>5.2.4.RELEASE</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-test</artifactId>
<version>5.2.4.RELEASE</version>
<scope>test</scope>
</dependency>
<!-- Java Mail坐標依賴 -->
<dependency>
<groupId>com.sun.mail</groupId>
<artifactId>javax.mail</artifactId>
<version>1.6.2</version>
</dependency>
配置郵件發(fā)送 bean
在 spring.xml 配置文件中設置郵件發(fā)送對應的bean標簽
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:context="http://www.springframework.org/schema/context"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context.xsd">
<!-- 開啟自動化掃描 -->
<context:component-scan base-package="com.xxxx"/>
<!-- 郵件發(fā)送器(提供了郵件發(fā)送接口、透明創(chuàng)建Java Mail的MimeMessage快鱼、及郵件發(fā)送的配置) -->
<bean id="mailSender" class="org.springframework.mail.javamail.JavaMailSenderImpl">
<property name="host" value="smtp.163.com" />
<property name="port" value="25" />
<property name="defaultEncoding" value="utf-8"></property>
<property name="username" value="用戶名"></property>
<property name="password" value="密碼"></property>
</bean>
<!-- 普通文本郵件對象 -->
<bean id="templateMessage" class="org.springframework.mail.SimpleMailMessage">
<property name="from" value="發(fā)件人的郵箱地址" />
<property name="subject" value="spring_mail" />
</bean>
</beans>
定義接口與實現類
定義接口
package com.xxxx.springMail;
/**
* 定義接口
*/
public interface OrderManager {
void placeOrder();
}
定義實現類
package com.xxxx.springMail;
import org.springframework.mail.MailException;
import org.springframework.mail.SimpleMailMessage;
import org.springframework.mail.javamail.JavaMailSenderImpl;
import org.springframework.stereotype.Service;
import javax.annotation.Resource;
@Service
public class SimpleOrderManager implements OrderManager {
@Resource
private JavaMailSenderImpl mailSender;
@Resource
private SimpleMailMessage templateMessage;
@Override
public void placeOrder() {
// 獲取郵件對象
SimpleMailMessage msg = new SimpleMailMessage(this.templateMessage);
// 設置郵件收件人的郵箱地址
msg.setTo("收件人的郵箱地址");
// 設置郵件內容
msg.setText("Hello Spring Mail");
try{
// 發(fā)送郵件
this.mailSender.send(msg);
} catch (MailException ex) {
System.err.println(ex.getMessage());
}
}
}
郵件發(fā)送測試
/**
* 發(fā)送郵件
* @param args
*/
public static void main(String[] args) {
ApplicationContext ac=new ClassPathXmlApplicationContext("spring.xml");
SimpleOrderManager simpleOrderManager =
(SimpleOrderManager) ac.getBean("simpleOrderManager");
simpleOrderManager.placeOrder();
}
發(fā)送附件
/**
* 發(fā)送包含附件的郵件
* @param args
* @throws MessagingException
*/
public static void main(String[] args) throws MessagingException {
ApplicationContext ac = new ClassPathXmlApplicationContext("spring.xml");
JavaMailSender mailSender= (JavaMailSender) ac.getBean("mailSender");
MimeMessage message= mailSender.createMimeMessage();
message.setSubject("spring_mail"); // 郵件主題
// 創(chuàng)建帶有附件的消息幫組類
MimeMessageHelper helper = new MimeMessageHelper(message,true,"utf-8");
helper.setTo(new InternetAddress("收件人的郵箱地址"));//設置接收人
helper.setText("Thank you for ordering!"); // 郵件內容
helper.setFrom("發(fā)件人的郵箱地址"); // 發(fā)件人
// 設置附件
File file = new File("C:\\work\\郵件附件.txt");
// 添加附件
helper.addAttachment(file.getName(), file);
// 發(fā)送郵件
mailSender.send(message);
}