概述
郵件相關(guān)的標(biāo)準(zhǔn)
廠商所提供的 JavaMail 服務(wù)程序可以有選擇地實(shí)現(xiàn)某些郵件協(xié)議,常見的郵件協(xié)議包括:
SMTP(Simple Mail Transfer Protocol)
:即簡單郵件傳輸協(xié)議,它是一組用于由源地址到目的地址傳送郵件的規(guī)則,由它來控制信件的中轉(zhuǎn)方式。
POP3(Post Office Protocol - Version 3)
:即郵局協(xié)議版本 3 ,用于接收電子郵件的標(biāo)準(zhǔn)協(xié)議。
IMAP(Internet Mail Access Protocol)
:即 Internet 郵件訪問協(xié)議。是 POP3 的替代協(xié)議。
這三種協(xié)議都有對應(yīng) SSL 加密傳輸?shù)膮f(xié)議,分別是 **SMTPS **, **POP3S **和 **IMAPS **。
MIME(Multipurpose Internet Mail Extensions)
:即多用途因特網(wǎng)郵件擴(kuò)展標(biāo)準(zhǔn)。它不是郵件傳輸協(xié)議。但對傳輸內(nèi)容的消息、附件及其它的內(nèi)容定義了格式。
JavaMail 簡介
JavaMail 是由 Sun 發(fā)布的用來處理 email 的 API 。它并沒有包含在 Java SE 中,而是作為 Java EE 的一部分。
mail.jar
:此 JAR 文件包含 JavaMail API 和 Sun 提供的 SMTP 、 IMAP 和 POP3 服務(wù)提供程序;
activation.jar
:此 JAR 文件包含 JAF API 和 Sun 的實(shí)現(xiàn)。
JavaMail 包中用于處理電子郵件的核心類是: Properties
、 Session
、 Message
、 Address
、 Authenticator
、 Transport
、 Store
等。
郵件傳輸過程
如上圖,電子郵件的處理步驟如下:
創(chuàng)建一個(gè) Session 對象。
Session 對象創(chuàng)建一個(gè) Transport 對象 /Store 對象,用來發(fā)送 / 保存郵件。
Transport 對象 /Store 對象連接郵件服務(wù)器。
Transport 對象 /Store 對象創(chuàng)建一個(gè) Message 對象 ( 也就是郵件內(nèi)容 ) 。
Transport 對象發(fā)送郵件; Store 對象獲取郵箱的郵件。
Message 結(jié)構(gòu)
MimeMessage
類:代表整封郵件。
MimeBodyPart
類:代表郵件的一個(gè) MIME 信息。
MimeMultipart
類:代表一個(gè)由多個(gè) MIME 信息組合成的組合 MIME 信息。
JavaMail 的核心類
JavaMail 對收發(fā)郵件進(jìn)行了高級的抽象,形成了一些關(guān)鍵的的接口和類,它們構(gòu)成了程序的基礎(chǔ),下面我們分別來了解一下這些最常見的對象。
java.util.Properties類(屬性對象)
java.util.Properties 類代表一組屬性集合。
它的每一個(gè)鍵和值都是 String 類型。
由于 JavaMail 需要和郵件服務(wù)器進(jìn)行通信,這就要求程序提供許多諸如服務(wù)器地址、端口、用戶名、密碼等信息, JavaMail 通過 Properties 對象封裝這些屬性信息。
例: 如下面的代碼封裝了幾個(gè)屬性信息:
Properties prop = new Properties();
prop.setProperty("mail.debug", "true");
prop.setProperty("mail.host", "[email protected]");
prop.setProperty("mail.transport.protocol", "smtp");
prop.setProperty("mail.smtp.auth", "true");
針對不同的的郵件協(xié)議, JavaMail 規(guī)定了服務(wù)提供者必須支持一系列屬性,
下表是一些常見屬性(屬性值都以 String 類型進(jìn)行設(shè)置,屬性類型欄僅表示屬性是如何被解析的):
關(guān)鍵詞 | 類型 | 描述 |
---|---|---|
mail.debug | boolean | debug 開關(guān)。 |
mail.host | String | 指定發(fā)送、接收郵件的默認(rèn)郵箱服務(wù)器。 |
mail.store.protocol | String | 指定接收郵件的協(xié)議。 |
mail.transport.protocol | String | 指定發(fā)送郵件的協(xié)議。 |
mail.debug.auth | boolean | debug 輸出中是否包含認(rèn)證命令。默認(rèn)是 false 。 |
詳情請參考官方 API 文檔:
https://javamail.java.net/nonav/docs/api/ 。
javax.mail.Session類(會(huì)話對象)
Session
表示一個(gè)郵件會(huì)話。
Session 的主要作用包括兩個(gè)方面:
接收各種配置屬性信息:通過 Properties 對象設(shè)置的屬性信息;
初始化 JavaMail 環(huán)境:根據(jù) JavaMail 的配置文件,初始化 JavaMail 環(huán)境,以便通過 Session 對象創(chuàng)建其他重要類的實(shí)例。
JavaMail 在 Jar 包的 META-INF 目錄下,通過以下文件提供了基本配置信息,以便 session 能夠根據(jù)這個(gè)配置文件加載提供者的實(shí)現(xiàn)類:
javamail.default.providers
javamail.default.address.map
例:
Properties props = new Properties();
props.setProperty("mail.transport.protocol", "smtp");
Session session = Session.getInstance(props);
javax.mail.Transport類(郵件傳輸)
郵件操作只有發(fā)送或接收兩種處理方式。
JavaMail 將這兩種不同操作描述為傳輸( javax.mail.Transport )和存儲( javax.mail.Store ),傳輸對應(yīng)郵件的發(fā)送,而存儲對應(yīng)郵件的接收。
getTransport
**: **Session 類中的 getTransport **() **有多個(gè)重載方法,可以用來創(chuàng)建 Transport 對象。
connect
**: **如果設(shè)置了認(rèn)證命令—— mail.smtp.auth ,那么使用 Transport 類的 connect 方法連接服務(wù)器時(shí),則必須加上用戶名和密碼。
sendMessage
: Transport 類的 sendMessage 方法用來發(fā)送郵件消息。
close
: Transport 類的 close 方法用來關(guān)閉和郵件服務(wù)器的連接。
javax.mail.Store 類(郵件存儲 )
getStore
:Session 類中的 getStore () 有多個(gè)重載方法,可以用來創(chuàng)建 Store 對象。
connect
: 如果設(shè)置了認(rèn)證命令—— mail.smtp.auth ,那么使用 Store 類的 connect 方法連接服務(wù)器時(shí),則必須加上用戶名和密碼。
getFolder
:Store 類的 getFolder 方法可以 獲取郵箱內(nèi)的郵件夾 Folder 對象
close
: Store 類的 close 方法用來關(guān)閉和郵件服務(wù)器的連接。
javax.mail.Message類(消息對象)
javax.mail.Message
是個(gè)抽象類,只能用子類去實(shí)例化,多數(shù)情況下為 javax.mail.internet.MimeMessage
。
MimeMessage
代表 MIME 類型的電子郵件消息。
要?jiǎng)?chuàng)建一個(gè) Message ,需要將 Session 對象傳遞給 MimeMessage
構(gòu)造器:
MimeMessage message = new MimeMessage(session);
注意:還存在其它構(gòu)造器,如用按 RFC822 格式的輸入流來創(chuàng)建消息。
setFrom :設(shè)置郵件的發(fā)件人
setRecipient :設(shè)置郵件的發(fā)送人、抄送人、密送人
三種預(yù)定義的地址類型是:
Message.RecipientType.TO
:收件人
Message.RecipientType.CC
:抄送人
Message.RecipientType.BCC
:密送人
setSubject
:設(shè)置郵件的主題
setContent
:設(shè)置郵件內(nèi)容
setText
:如果郵件內(nèi)容是純文本,可以使用此接口設(shè)置文本內(nèi)容。
javax.mail.Address類(地址)
一旦您創(chuàng)建了 Session 和 Message ,并將內(nèi)容填入消息后,就可以用 Address 確定信件地址了。和 Message 一樣, Address 也是個(gè)抽象類。您用的是 javax.mail.internet.InternetAddress 類。
若創(chuàng)建的地址只包含電子郵件地址,只要傳遞電子郵件地址到構(gòu)造器就行了。
例:
Address address = new InternetAddress("[email protected]");
Authenticator類(認(rèn)證者)
與 java.net 類一樣, JavaMail API 也可以利用 Authenticator
通過用戶名和密碼訪問受保護(hù)的資源。對于 JavaMail API 來說,這些資源就是郵件服務(wù)器。Authenticator
在 javax.mail 包中,而且它和 java.net 中同名的類 Authenticator 不同。兩者并不共享同一個(gè) Authenticator ,因?yàn)?JavaMail API 用于 Java 1.1 ,它沒有 java.net 類別。
要使用 Authenticator ,先創(chuàng)建一個(gè)抽象類的子類,并從 getPasswordAuthentication()
方法中返回 PasswordAuthentication
實(shí)例。創(chuàng)建完成后,您必需向 session 注冊 Authenticator
。然后,在需要認(rèn)證的時(shí)候,就會(huì)通知 Authenticator
。您可以彈出窗口,也可以從配置文件中(雖然沒有加密是不安全的)讀取用戶名和密碼,將它們作為 PasswordAuthentication
對象返回給調(diào)用程序。
例:
Properties props = new Properties();
Authenticator auth = new MyAuthenticator();
Session session = Session.getDefaultInstance(props, auth);
實(shí)例
發(fā)送文本郵件
public static void main(String[] args) throws Exception {
Properties prop = new Properties();
prop.setProperty("mail.debug", "true");
prop.setProperty("mail.host", MAIL_SERVER_HOST);
prop.setProperty("mail.transport.protocol", "smtp");
prop.setProperty("mail.smtp.auth", "true");
// 1、創(chuàng)建session
Session session = Session.getInstance(prop);
Transport ts = null;
// 2、通過session得到transport對象
ts = session.getTransport();
// 3、連上郵件服務(wù)器
ts.connect(MAIL_SERVER_HOST, USER, PASSWORD);
// 4、創(chuàng)建郵件
MimeMessage message = new MimeMessage(session);
// 郵件消息頭
message.setFrom(new InternetAddress(MAIL_FROM)); // 郵件的發(fā)件人
message.setRecipient(Message.RecipientType.TO, new InternetAddress(MAIL_TO)); // 郵件的收件人
message.setRecipient(Message.RecipientType.CC, new InternetAddress(MAIL_CC)); // 郵件的抄送人
message.setRecipient(Message.RecipientType.BCC, new InternetAddress(MAIL_BCC)); // 郵件的密送人
message.setSubject("測試文本郵件"); // 郵件的標(biāo)題
// 郵件消息體
message.setText("天下無雙。");
// 5、發(fā)送郵件
ts.sendMessage(message, message.getAllRecipients());
ts.close();
}
發(fā)送 HTML 格式的郵件
public static void main(String[] args) throws Exception {
Properties prop = new Properties();
prop.setProperty("mail.debug", "true");
prop.setProperty("mail.host", MAIL_SERVER_HOST);
prop.setProperty("mail.transport.protocol", "smtp");
prop.setProperty("mail.smtp.auth", "true");
// 1、創(chuàng)建session
Session session = Session.getInstance(prop);
Transport ts = null;
// 2、通過session得到transport對象
ts = session.getTransport();
// 3、連上郵件服務(wù)器
ts.connect(MAIL_SERVER_HOST, USER, PASSWORD);
// 4、創(chuàng)建郵件
MimeMessage message = new MimeMessage(session);
// 郵件消息頭
message.setFrom(new InternetAddress(MAIL_FROM)); // 郵件的發(fā)件人
message.setRecipient(Message.RecipientType.TO, new InternetAddress(MAIL_TO)); // 郵件的收件人
message.setRecipient(Message.RecipientType.CC, new InternetAddress(MAIL_CC)); // 郵件的抄送人
message.setRecipient(Message.RecipientType.BCC, new InternetAddress(MAIL_BCC)); // 郵件的密送人
message.setSubject("測試HTML郵件"); // 郵件的標(biāo)題
String htmlContent = "<h1>Hello</h1>" + "<p>顯示圖片1.jpg</p>";
MimeBodyPart text = new MimeBodyPart();
text.setContent(htmlContent, "text/html;charset=UTF-8");
MimeBodyPart image = new MimeBodyPart();
DataHandler dh = new DataHandler(new FileDataSource("D:\\05_Datas\\圖庫\\吉他少年背影.png"));
image.setDataHandler(dh);
image.setContentID("abc.jpg");
// 描述數(shù)據(jù)關(guān)系
MimeMultipart mm = new MimeMultipart();
mm.addBodyPart(text);
mm.addBodyPart(image);
mm.setSubType("related");
message.setContent(mm);
message.saveChanges();
// 5、發(fā)送郵件
ts.sendMessage(message, message.getAllRecipients());
ts.close();
}
發(fā)送帶附件的郵件
public static void main(String[] args) throws Exception {
Properties prop = new Properties();
prop.setProperty("mail.debug", "true");
prop.setProperty("mail.host", MAIL_SERVER_HOST);
prop.setProperty("mail.transport.protocol", "smtp");
prop.setProperty("mail.smtp.auth", "true");
// 1、創(chuàng)建session
Session session = Session.getInstance(prop);
// 2、通過session得到transport對象
Transport ts = session.getTransport();
// 3、連上郵件服務(wù)器
ts.connect(MAIL_SERVER_HOST, USER, PASSWORD);
// 4、創(chuàng)建郵件
MimeMessage message = new MimeMessage(session);
// 郵件消息頭
message.setFrom(new InternetAddress(MAIL_FROM)); // 郵件的發(fā)件人
message.setRecipient(Message.RecipientType.TO, new InternetAddress(MAIL_TO)); // 郵件的收件人
message.setRecipient(Message.RecipientType.CC, new InternetAddress(MAIL_CC)); // 郵件的抄送人
message.setRecipient(Message.RecipientType.BCC, new InternetAddress(MAIL_BCC)); // 郵件的密送人
message.setSubject("測試帶附件郵件"); // 郵件的標(biāo)題
MimeBodyPart text = new MimeBodyPart();
text.setContent("郵件中有兩個(gè)附件。", "text/html;charset=UTF-8");
// 描述數(shù)據(jù)關(guān)系
MimeMultipart mm = new MimeMultipart();
mm.setSubType("related");
mm.addBodyPart(text);
String[] files = {
"D:\\00_Temp\\temp\\1.jpg", "D:\\00_Temp\\temp\\2.png"
};
// 添加郵件附件
for (String filename : files) {
MimeBodyPart attachPart = new MimeBodyPart();
attachPart.attachFile(filename);
mm.addBodyPart(attachPart);
}
message.setContent(mm);
message.saveChanges();
// 5、發(fā)送郵件
ts.sendMessage(message, message.getAllRecipients());
ts.close();
}
獲取郵箱中的郵件
public static void main(String[] args) throws Exception {
// 創(chuàng)建一個(gè)有具體連接信息的Properties對象
Properties prop = new Properties();
prop.setProperty("mail.debug", "true");
prop.setProperty("mail.store.protocol", "pop3");
prop.setProperty("mail.pop3.host", MAIL_SERVER_HOST);
// 1、創(chuàng)建session
Session session = Session.getInstance(prop);
// 2、通過session得到Store對象
Store store = session.getStore();
// 3、連上郵件服務(wù)器
store.connect(MAIL_SERVER_HOST, USER, PASSWORD);
// 4、獲得郵箱內(nèi)的郵件夾
Folder folder = store.getFolder("inbox");
folder.open(Folder.READ_ONLY);
// 獲得郵件夾Folder內(nèi)的所有郵件Message對象
Message[] messages = folder.getMessages();
for (int i = 0; i < messages.length; i++) {
String subject = messages[i].getSubject();
String from = (messages[i].getFrom()[0]).toString();
System.out.println("第 " + (i + 1) + "封郵件的主題:" + subject);
System.out.println("第 " + (i + 1) + "封郵件的發(fā)件人地址:" + from);
}
// 5、關(guān)閉
folder.close(false);
store.close();
}
轉(zhuǎn)發(fā)郵件
例:獲取指定郵件夾下的第一封郵件并轉(zhuǎn)發(fā)
public static void main(String[] args) throws Exception {
Properties prop = new Properties();
prop.put("mail.store.protocol", "pop3");
prop.put("mail.pop3.host", MAIL_SERVER_POP3);
prop.put("mail.pop3.starttls.enable", "true");
prop.put("mail.smtp.auth", "true");
prop.put("mail.smtp.host", MAIL_SERVER_SMTP);
// 1、創(chuàng)建session
Session session = Session.getDefaultInstance(prop);
// 2、讀取郵件夾
Store store = session.getStore("pop3");
store.connect(MAIL_SERVER_POP3, USER, PASSWORD);
Folder folder = store.getFolder("inbox");
folder.open(Folder.READ_ONLY);
// 獲取郵件夾中第1封郵件信息
Message[] messages = folder.getMessages();
if (messages.length <= 0) {
return;
}
Message message = messages[0];
// 打印郵件關(guān)鍵信息
String from = InternetAddress.toString(message.getFrom());
if (from != null) {
System.out.println("From: " + from);
}
String replyTo = InternetAddress.toString(message.getReplyTo());
if (replyTo != null) {
System.out.println("Reply-to: " + replyTo);
}
String to = InternetAddress.toString(message.getRecipients(Message.RecipientType.TO));
if (to != null) {
System.out.println("To: " + to);
}
String subject = message.getSubject();
if (subject != null) {
System.out.println("Subject: " + subject);
}
Date sent = message.getSentDate();
if (sent != null) {
System.out.println("Sent: " + sent);
}
// 設(shè)置轉(zhuǎn)發(fā)郵件信息頭
Message forward = new MimeMessage(session);
forward.setFrom(new InternetAddress(MAIL_FROM));
forward.setRecipient(Message.RecipientType.TO, new InternetAddress(MAIL_TO));
forward.setSubject("Fwd: " + message.getSubject());
// 設(shè)置轉(zhuǎn)發(fā)郵件內(nèi)容
MimeBodyPart bodyPart = new MimeBodyPart();
bodyPart.setContent(message, "message/rfc822");
Multipart multipart = new MimeMultipart();
multipart.addBodyPart(bodyPart);
forward.setContent(multipart);
forward.saveChanges();
Transport ts = session.getTransport("smtp");
ts.connect(USER, PASSWORD);
ts.sendMessage(forward, forward.getAllRecipients());
folder.close(false);
store.close();
ts.close();
System.out.println("message forwarded successfully....");
}