自拍偷在线精品自拍偷,亚洲欧美中文日韩v在线观看不卡

JavaMail API詳解(上)

開發(fā) 后端
JavaMail API詳解共分為兩個部分,本文是其第一部分,分為JavaMail API簡介、相關(guān)協(xié)議一覽、JavaMail的安裝以及對JavaMail API的初步認(rèn)識。

一、JavaMail API簡介
JavaMail API是讀取、撰寫、發(fā)送電子信息的可選包。我們可用它來建立如Eudora、Foxmail、MS Outlook Express一般的郵件用戶代理程序(Mail User Agent,簡稱MUA)。而不是像sendmail或者其它的郵件傳輸代理(Mail Transfer Agent,簡稱MTA)程序那樣可以傳送、遞送、轉(zhuǎn)發(fā)郵件。從另外一個角度來看,我們這些電子郵件用戶日常用MUA程序來讀寫郵件,而MUA依賴著MTA處理郵件的遞送。
在清楚了到MUA與MTA之間的關(guān)系后,讓我們看看JavaMail API是如何提供信息訪問功能的吧!JavaMail API被設(shè)計用于以不依賴協(xié)議的方式去發(fā)送和接收電子信息,這個API被分為兩大部分:

基本功能:如何以不依賴于協(xié)議的方式發(fā)送接收電子信息,這也是本文所要描述的,不過在下文中,大家將看到這只是一廂情愿而已。
第二個部分則是依賴特定協(xié)議的,比如SMTP、POP、IMAP、NNTP協(xié)議。在這部分的JavaMail API是為了和服務(wù)器通訊,并不在本文的內(nèi)容中。

二、相關(guān)協(xié)議一覽
在我們步入JavaMail API之前,先看一下API所涉及的協(xié)議。以下便是大家日常所知、所樂于使用的4大信息傳輸協(xié)議:
SMTP
POP
IMAP
MIME
當(dāng)然,上面的4個協(xié)議,并不是全部,還有NNTP和其它一些協(xié)議可用于傳輸信息,但是由于不常用到,所以本文便不提及了。理解這4個基本的協(xié)議有助于我們更好的使用JavaMail API。然而JavaMail API是被設(shè)計為與協(xié)議無關(guān)的,目前我們并不能克服這些協(xié)議的束縛。確切的說,如果我們使用的功能并不被我們選擇的協(xié)議支持,那么JavaMail API并不可能如魔術(shù)師一樣神奇的賦予我們這種能力。

1.SMTP
簡單郵件傳輸協(xié)議定義了遞送郵件的機(jī)制。在下文中,我們將使用基于Java-Mail的程序與公司或者ISP的SMTP服務(wù)器進(jìn)行通訊。這個SMTP服務(wù)器將郵件轉(zhuǎn)發(fā)到接收者的SMTP服務(wù)器,直至***被接收者通過POP或者IMAP協(xié)議獲取。這并不需要SMTP服務(wù)器使用支持授權(quán)的郵件轉(zhuǎn)發(fā),但是卻的確要注意SMTP服務(wù)器的正確設(shè)置(SMTP服務(wù)器的設(shè)置與JavaMail API無關(guān))。

2.POP
POP是一種郵局協(xié)議,目前為第3個版本,即眾所周知的POP3。POP定義了一種用戶如何獲得郵件的機(jī)制。它規(guī)定了每個用戶使用一個單獨(dú)的郵箱。大多數(shù)人在使用POP時所熟悉的功能并非都被支持,例如查看郵箱中的新郵件數(shù)量。而這個功能是微軟的Outlook內(nèi)建的,那么就說明微軟Outlook之類的郵件客戶端軟件是通過查詢最近收到的郵件來計算新郵件的數(shù)量來實現(xiàn)前面所說的功能。因此在我們使用JavaMail API時需要注意,當(dāng)需要獲得如前面所講的新郵件數(shù)量之類的信息時,我們不得不自己進(jìn)行計算。

3.IMAP
IMAP使用在接收信息的高級協(xié)議,目前版本為第4版,所以也被稱為IMAP4。需要注意的是在使用IMAP時,郵件服務(wù)器必須支持該協(xié)議。從這個方面講,我們并不能完全使用IMAP來替代POP,不能期待IMAP在任何地方都被支持。假如郵件服務(wù)器支持IMAP,那么我們的郵件程序?qū)⒛軌蚓哂幸韵卤籌MAP所支持的特性:每個用戶在服務(wù)器上可具有多個目錄,這些目錄能在多個用戶之間共享。
其與POP相比高級之處顯而易見,但是在嘗試采取IMAP時,我們認(rèn)識到它并不是十分***的:由于IMAP需要從其它服務(wù)器上接收新信息,將這些信息遞送給用戶,維護(hù)每個用戶的多個目錄,這都為郵件服務(wù)器帶來了高負(fù)載。并且IMAP與POP的一個不同之處是POP用戶在接收郵件時將從郵件服務(wù)器上下載郵件,而IMAP允許用戶直接訪問郵件目錄,所以在郵件服務(wù)器進(jìn)行備份作業(yè)時,由于每個長期使用此郵件系統(tǒng)的用戶所用的郵件目錄會占有很大的空間,這將直接導(dǎo)致郵件服務(wù)器上磁盤空間暴漲。

4.MIME
MIME并不是用于傳送郵件的協(xié)議,它作為多用途郵件的擴(kuò)展定義了郵件內(nèi)容的格式:信息格式、附件格式等等。一些RFC標(biāo)準(zhǔn)都涉及了MIME:RFC 822, RFC 2045, RFC 2046, RFC 2047,有興趣的Matrixer可以閱讀一下。而作為JavaMail API的開發(fā)者,我們并不需關(guān)心這些格式定義,但是這些格式被用在了程序中。

5.NNTP和其它的第三方協(xié)議
正因為JavaMail API在設(shè)計時考慮到與第三方協(xié)議實現(xiàn)提供商之間的分離,故我們可以很容易的添加一些第三方協(xié)議。SUN維護(hù)著一個第三方協(xié)議實現(xiàn)提供商的列表:http://java.sun.com/products/javamail/Third_Party.html,通過此列表我們可以找到所需要的而又不被SUN提供支持的第三方協(xié)議:比如NNTP這個新聞組協(xié)議和S/MIME這個安全的MIME協(xié)議。

三、安裝JavaMail及其相關(guān)
1.安裝JavaMail
為了使用JavaMail API,需要從http://java.sun.com/products/javamail/downloads/index.html下載文件名格式為javamail-[version].zip的文件(這個文件中包括了JavaMail實現(xiàn)),并將其中的mail.jar文件添加到CLASSPATH中。這個實現(xiàn)提供了對SMTP、IMAP4、POP3的支持。
注意:在安裝JavaMail實現(xiàn)之后,我們將在demo目錄中發(fā)現(xiàn)許多有趣的簡單實例程序。
在安裝了JavaMail之后,我們還需要安裝JavaBeans Activation Framework,因為這個框架是JavaMail API所需要的。如果我們使用J2EE的話,那么我們并無需單獨(dú)下載JavaMail,因為它存在于J2EE.jar中,只需將J2EE.jar加入到CLASSPATH即可。

2.安裝JavaBeans Activation Framework
從http://java.sun.com/products/javabeans/glasgow/jaf.html下載JavaBeans Activation Framework,并將其添加到CLASSPATH中。此框架增加了對任何數(shù)據(jù)塊的分類、以及對它們的處理的特性。這些特性是JavaMail API需要的。雖然聽起來這些特性非常模糊,但是它對于我們的JavaMail API來說只是提供了基本的MIME類型支持。
到此為止,我們應(yīng)當(dāng)把mail.jar和activation.jar都添加到了CLASSPATH中。
當(dāng)然如果從方便的角度講,直接把這兩個Jar文件復(fù)制到JRE目錄的lib/ext目錄中也可以。

四、初步認(rèn)識JavaMail API
1.了解我們的JavaMail環(huán)境
A.縱覽JavaMail核心類結(jié)構(gòu)
打開JavaMail.jar文件,我們將發(fā)現(xiàn)在javax.mail的包下面存在著一些核心類:Session、Message、Address、Authenticator、Transport、Store、Folder。而且在javax.mail.internet包中還有一些常用的子類。
B.Session
Session類定義了基本的郵件會話。就像Http會話那樣,我們進(jìn)行收發(fā)郵件的工作都是基于這個會話的。Session對象利用了java.util.Properties對象獲得了郵件服務(wù)器、用戶名、密碼信息和整個應(yīng)用程序都要使用到的共享信息。
Session類的構(gòu)造方法是私有的,所以我們可以使用Session類提供的getDefaultInstance()這個靜態(tài)工廠方法獲得一個默認(rèn)的Session對象:

  1. Properties props = new Properties();  
  2. // fill props with any informationSession session 
  3. = Session.getDefaultInstance(props, null);  

或者使用getInstance()這個靜態(tài)工廠方法獲得自定義的Session:

  1. Properties props = new Properties();  
  2. // fill props with any informationSession session = Session.getInstance(props, null);  

從上面的兩個例子中不難發(fā)現(xiàn),getDefaultInstance()和getInstance()方法的第二個參數(shù)都是null,這是因為在上面的例子中并沒有使用到郵件授權(quán),下文中將對授權(quán)進(jìn)行詳細(xì)介紹。
從很多的實例看,在對mail server進(jìn)行訪問的過程中使用共享的Session是足夠的,即使是工作在多個用戶郵箱的模式下也不例外。

C.Message
當(dāng)我們建立了Session對象后,便可以被發(fā)送的構(gòu)造信息體了。在這里SUN提供了Message類型來幫助開發(fā)者完成這項工作。由于Message是一個抽象類,大多數(shù)情況下,我們使用javax.mail.internet.MimeMessage這個子類,該類是使用MIME類型、MIME信息頭的郵箱信息。信息頭只能使用US-ASCII字符,而非ASCII字符將通過編碼轉(zhuǎn)換為ASCII的方式使用。
為了建立一個MimeMessage對象,我們必須將Session對象作為MimeMessage構(gòu)造方法的參數(shù)傳入:

MimeMessage message = new MimeMessage(session);

注意:對于MimeMessage類來講存在著多種構(gòu)造方法,比如使用輸入流作為參數(shù)的構(gòu)造方法。

在建立了MimeMessage對象后,我們需要設(shè)置它的各個part,對于MimeMessage類來說,這些part就是MimePart接口。最基本的設(shè)置信息內(nèi)容的方法就是通過表示信息內(nèi)容和米么類型的參數(shù)調(diào)用setContent()方法:

message.setContent("Hello", "text/plain");

然而,如果我們所使用的MimeMessage中信息內(nèi)容是文本的話,我們便可以直接使用setText()方法來方便的設(shè)置文本內(nèi)容。

message.setText("Hello");

前面所講的兩種方法,對于文本信息,后者更為合適。而對于其它的一些信息類型,比如HTML信息,則要使用前者。
別忘記了,使用setSubject()方法對郵件設(shè)置郵件主題:

message.setSubject("First");


D.Address
到這里,我們已經(jīng)建立了Session和Message,下面將介紹如何使用郵件地址類:Address。像Message一樣,Address類也是一個抽象類,所以我們將使用javax.mail.internet.InternetAddress這個子類。
通過傳入代表郵件地址的字符串,我們可以建立一個郵件地址類:

Address address = new InternetAddress("president@whitehouse.gov");

如果要在郵件地址后面增加名字的話,可以通過傳遞兩個參數(shù):代表郵件地址和名字的字符串來建立一個具有郵件地址和名字的郵件地址類:

Address address = new InternetAddress("president@whitehouse.gov", "George Bush");

本文在這里所講的郵件地址類是為了設(shè)置郵件信息的發(fā)信人和收信人而準(zhǔn)備的,在建立了郵件地址類后,我們通過message的setFrom()和setReplyTo()兩種方法設(shè)置郵件的發(fā)信人:

message.setFrom(address);message.setReplyTo(address);

若在郵件中存在多個發(fā)信人地址,我們可用addForm()方法增加發(fā)信人:

Address address[] = ...;message.addFrom(address);

為了設(shè)置收信人,我們使用addRecipient()方法增加收信人,此方法需要使用Message.RecipientType的常量來區(qū)分收信人的類型:

message.addRecipient(type, address)

下面是Message.RecipientType的三個常量:

  1. Message.RecipientType.TO  
  2. Message.RecipientType.CC  
  3. Message.RecipientType.BCC 

因此,如果我們要發(fā)送郵件給總統(tǒng),并發(fā)用一個副本給***夫人的話,下面的方法將被用到:

  1. Address toAddress = new InternetAddress("vice.president@whitehouse.gov");  
  2. Address ccAddress = new InternetAddress("first.lady@whitehouse.gov");  
  3. message.addRecipient(Message.RecipientType.TO, toAddress);  
  4. message.addRecipient(Message.RecipientType.CC, ccAddress);  

JavaMail API并沒有提供檢查郵件地址有效性的機(jī)制。當(dāng)然我們可以自己完成這個功能:驗證郵件地址的字符是否按照RFC822規(guī)定的格式書寫或者通過DNS服務(wù)器上的MX記錄驗證等。

E.Authenticator
像java.net類那樣,JavaMail API通過使用授權(quán)者類(Authenticator)以用戶名、密碼的方式訪問那些受到保護(hù)的資源,在這里“資源”就是指郵件服務(wù)器。在javax.mail包中可以找到這個JavaMail的授權(quán)者類(Authenticator)。
在使用Authenticator這個抽象類時,我們必須采用繼承該抽象類的方式,并且該繼承類必須具有返回PasswordAuthentication對象(用于存儲認(rèn)證時要用到的用戶名、密碼)getPasswordAuthentication()方法。并且要在Session中進(jìn)行注冊,使Session能夠了解在認(rèn)證時該使用哪個類。
下面代碼片斷中的MyAuthenticator就是一個Authenticator的子類。

  1. Properties props = new Properties();  
  2. // fill props with any informationAuthenticator auth = new MyAuthenticator();  
  3. Session session = Session.getDefaultInstance(props, auth);  

F.Transport
在發(fā)送信息時,Transport類將被用到。這個類實現(xiàn)了發(fā)送信息的協(xié)議(通稱為SMTP),此類是一個抽象類,我們可以使用這個類的靜態(tài)方法send()來發(fā)送消息:

Transport.send(message);

當(dāng)然,方法是多樣的。我們也可由Session獲得相應(yīng)協(xié)議對應(yīng)的Transport實例。并通過傳遞用戶名、密碼、郵件服務(wù)器主機(jī)名等參數(shù)建立與郵件服務(wù)器的連接,并使用sendMessage()方法將信息發(fā)送,***關(guān)閉連接:

  1. message.saveChanges();   
  2. // implicit with send()Transport transport = session.getTransport("smtp");  
  3. transport.connect(host, username, password);  
  4. transport.sendMessage(message, message.getAllRecipients());transport.close(); 

評論:上面的方法是一個很好的方法,尤其是在我們在同一個郵件服務(wù)器上發(fā)送多個郵件時。因為這時我們將在連接郵件服務(wù)器后連續(xù)發(fā)送郵件,然后再關(guān)閉掉連接。send()這個基本的方法是在每次調(diào)用時進(jìn)行與郵件服務(wù)器的連接的,對于在同一個郵件服務(wù)器上發(fā)送多個郵件來講可謂低效的方式。
注意:如果需要在發(fā)送郵件過程中監(jiān)控mail命令的話,可以在發(fā)送前設(shè)置debug標(biāo)志:

session.setDebug(true)。


G.Store和Folder
接收郵件和發(fā)送郵件很類似都要用到Session。但是在獲得Session后,我們需要從Session中獲取特定類型的Store,然后連接到Store,這里的Store代表了存儲郵件的郵件服務(wù)器。在連接Store的過程中,極有可能需要用到用戶名、密碼或者Authenticator。

// Store store = session.getStore("imap");Store store = session.getStore("pop3");store.connect(host, username, password);

在連接到Store后,一個Folder對象即目錄對象將通過Store的getFolder()方法被返回,我們可從這個Folder中讀取郵件信息:

  1. Folder folder = store.getFolder("INBOX");  
  2. folder.open(Folder.READ_ONLY);  
  3. Message message[] = folder.getMessages();  

上面的例子首先從Store中獲得INBOX這個Folder(對于POP3協(xié)議只有一個名為INBOX的Folder有效),然后以只讀(Folder.READ_ONLY)的方式打開Folder,***調(diào)用Folder的getMessages()方法得到目錄中所有Message的數(shù)組。

注意:對于POP3協(xié)議只有一個名為INBOX的Folder有效,而對于IMAP協(xié)議,我們可以訪問多個Folder(想想前面講的IMAP協(xié)議)。而且SUN在設(shè)計Folder的getMessages()方法時采取了很智能的方式:首先接收新郵件列表,然后再需要的時候(比如讀取郵件內(nèi)容)才從郵件服務(wù)器讀取郵件內(nèi)容。
在讀取郵件時,我們可以用Message類的getContent()方法接收郵件或是writeTo()方法將郵件保存,getContent()方法只接收郵件內(nèi)容(不包含郵件頭),而writeTo()方法將包括郵件頭。

System.out.println(((MimeMessage)message).getContent());

在讀取郵件內(nèi)容后,別忘記了關(guān)閉Folder和Store。

folder.close(aBoolean);store.close();

傳遞給Folder.close()方法的boolean 類型參數(shù)表示是否在刪除操作郵件后更新Folder。

H.繼續(xù)向前進(jìn)!
在講解了以上的七個Java Mail核心類定義和理解了簡單的代碼片斷后,下文將詳細(xì)講解怎樣使用這些類實現(xiàn)JavaMail API所要完成的高級功能。

【編輯推薦】

  1. 對Java編程思想的忠告
  2. 和我共同了解Java是什么
  3. 著名的Java論壇和網(wǎng)站
  4. 2009年十大Java技術(shù)解決方案
  5. 2008最值得學(xué)習(xí)的五種JAVA技術(shù)
責(zé)任編輯:仲衡 來源: 百度博客
相關(guān)推薦

2009-06-16 10:10:40

JavaMail AP

2011-12-23 09:28:31

Java

2011-12-07 14:57:44

JavaNIO

2012-03-07 14:37:03

JavaJavaMail

2012-04-30 20:24:43

Android API

2009-08-03 13:13:52

C#調(diào)用Outlook

2020-11-04 13:18:34

WebAPIWeb Share A

2009-06-16 09:06:37

JavaMailJSP

2009-01-16 15:37:34

Oracle數(shù)據(jù)庫API

2022-04-21 09:00:00

API安全密鑰

2014-08-28 10:16:17

HTML5

2012-04-04 22:36:52

iOS5

2013-12-12 10:46:22

2020-11-05 10:40:18

ActiveMQ

2023-08-28 08:00:46

2009-07-01 14:05:05

JSP郵件系統(tǒng)

2015-12-08 09:16:32

JavaMail郵件發(fā)送總結(jié)

2011-03-01 15:02:54

Qt

2024-06-26 00:22:35

2009-11-13 09:24:58

JPA 2.0Criteria AP
點(diǎn)贊
收藏

51CTO技術(shù)棧公眾號