今日是JAVAWEB最后一課,JAVAMAIL。E-mail在當今的日常生活中已經成為人們重要的通信方式之一,在WEB應用中E -mail被做為與用戶通信的最重要方式。如今各大綜合性網站都有提供自己的mail服務,企業或各其他專業性網站也有自己的內部mail服務器,天于為工作交流與合作。所以,學習E-mail技術是十分重要的!
一、郵件傳輸協議:
有使用過桌面郵件客戶端的人都知道,關聯一個郵件帳戶,需要設置它的SMTP郵件發送服務器和POP3郵件接收服務器。
SMTP和POP3協議到底是什么?(老方的圖片):

1. 實線部分(lisi@sina.com向wangwu@sohu.com發送郵件):
使用郵件客戶端(這里使用的是OutLook,也可以是網頁郵件客戶端或其他郵件客戶端),使用SMTP協議向sina的郵件服務器發送郵件,服務器檢測收件人的郵箱地址是sohu的郵件服務。所以,通過SMTP協議轉發給sohu服務器,sohu服務器將郵件存儲到存儲設備中。
2. wangwu@sohu.com,登陸郵件客戶端。通過pop3協議,從POP3服務器接收自己帳戶的郵件。POP3從郵件服務器中讀取郵件發送給客戶端。
3. 虛線部分(wangwu@sohu.com向lisi@sina.com發送郵件)
過程與上邊的相同。
二、使用windwos的控制臺發送郵件(SMTP協議):
1.注冊一個郵件帳戶,比如:test@gmail.com。
2.在運行中輸入“cmd”打開控制臺程序。
3.輸入:telnet smtp.google.com 25,回車。使用windows的telnet程序連接gmail的郵件發送服務器,SMTP的默認端口為25。
4.輸入:auth login,回車。登陸。
5.輸入:(test)用戶名,必須是經過Base64編碼后的文本。
6.輸入:密碼,必須是經過Base64編碼后的文本。
7.輸入:mail from:<test@gmail.com>,回車。郵件開自,這里是自己給自己發郵件,也可以是其他郵件。
8.輸入:rcpt to:<test@gmail.com>,回車。郵件發送到。
9.輸入:Data,回車。接下來要輸入郵件內容。
10.輸入:郵件內容,回車。
11.輸入:.,回車。(空行中的點,代表內容結束)
12.輸入:quit,回車。退出!
Ok,郵件發送成功!
三、使用windows控制臺接收郵件(POP3協議):
1.在運行中輸入“cmd”打開控制臺程序。
2.輸入:telnet pop3.gmail.com 110,回車。使用windows的telnet程序連接gmail的郵件接收服務器,POP3的默認端口為110。
3.輸入:user test,回車。這里的用戶名不需要Base64編碼。
4.輸入:pass密碼,回車。這里的密碼不需要Base64編碼。
5.輸入:stat,回車。顯示郵箱的狀態:郵件的數量和總大小。
6.輸入:list,回車。索引列出各郵件,顯示郵件的索引和大小。
7輸入:retr index,回車。這是最重要的一條命令,顯示批定索引的郵件。
8.輸入:quit,回車。退出!
OK,郵件接收成功!
四、創建郵件RFC822文檔:
n RFC32文檔規定了如何編寫一封簡單的郵件:
n 郵件頭和郵件體,兩者使用空行分隔。
n 郵件頭:
u From字段,此處可以隨便填寫,比如發送冒充郵件。也有一些郵件服務器為此進行了檢查。
u To字段
u Subject字段,標題。
u Cc、bcc字段,抄送和密送。
n 郵件體:郵件內容
上邊的這些內容可以加在Data輸入之前,進行設置。這樣郵件就可以看到標題來自、以及抄送等內容。
Windows的OutLook郵件客戶端,只能接收使用RFC822規范創建的郵件,否則查詢郵件各項參數和內容都為空。
五、創建郵件的MIME協議:
1.MIME協議是對RFC822文檔的升級和補充,它描述了如何生成一封復雜郵件。通常我們把MIME協議描述的郵件稱之為MIME郵件,MIME協議描述的數據稱之為MIME消息。
2.對于一封復雜郵件,如果包含了多個不同的數據,MIME協議規定了要使用容器對多段數據進行分隔,并使用Content-Type頭字段對數據的類型、以及多個數據之間的關系進行描述。(查看outlook郵件源文件)
MIME協議十分經典,WEB應用中使用的文件上傳正是此協議!
六、協議中的字段
1. Content-type字段:
數據類型 video:
以“主類型/子類型”的形式出現,主類型有text、image、audio、video、application、multipart、message等,分別表示文本、圖片、音頻、視頻、應用程序、組合結構、消息等。每個主類型下面都有多個子類型,例如text主類型包含plain、html、xml、css等子類型。
數據的關系:
multipart/mixed、multipart/related、multipart/alternative
2. Content-Disposition頭字段:
Content-Disposition頭字段用于指定郵件閱讀程序處理數據內容的方式,有inline和attachment兩種標準方式,inline表示直接處理,而attachment表示當作附件處理。如果將Content-Disposition設置為attachment,在其后還可以指定filename屬性,如下所示:
Content-Disposition: attachment; filename=“1.bmp”
上面的MIME頭字段表示MIME消息體的內容為郵件附件,附件名“1.bmp”。
3.Content-ID頭字段
Content-ID頭字段用于為“multipart/related”組合消息中的內嵌資源指定一個唯一標識號,在HTML格式的正文中可以使用這個唯一標識號來引用該內嵌資源。例如,假設將一個表示內嵌圖片的MIME消息的Content-ID頭字段設置為如下形式:
Content-ID: it315logo_gif
那么,在HTML正文中就需要使用如下HTML語句來引用該圖片資源:
<img src="cid:it315logo_gif">
注意,在引用Content-ID頭字段標識的內嵌資源時,要在資源的唯一標識號前面加上“cid:”,以說明要采用唯一標識號對資源進行引用。
七、發送最復雜郵件的程序
下面,我們來看一個發送最復雜的郵件程序(發送:文本內容、圖片、附件):
import java.util.Properties; import javax.activation.*; import javax.mail.*; import javax.mail.Message.RecipientType; import javax.mail.internet.*; public class MySmtp { public static void main(String[] args) throws Exception { String host = "smtp.google.com"; String from = "test@gmail.com"; String username = "test"; String password = "123456"; // 設置郵件的參數,根據參數生成會話。 Properties prop = new Properties(); prop.setProperty("mail.host", host); prop.setProperty("mail.transport.protocol", "smtp"); prop.setProperty("mail.smtp.auth", "true"); Session session = Session.getDefaultInstance(prop); session.setDebug(true); // 獲取郵件內容 MimeMessage message = getMessage(from, from); // 連接服務器,發送郵件 Transport ts = session.getTransport(); ts.connect(username, password); ts.sendMessage(message, message.getAllRecipients()); ts.close(); } // 此方法生成郵件的內容 private static MimeMessage getMessage(String from, String recipient) throws Exception{ MimeMessage message = new MimeMessage(Session .getDefaultInstance(new Properties())); message.setFrom(new InternetAddress(from)); message.setRecipient(RecipientType.TO, new InternetAddress( recipient)); message.setSubject("把這功能學會了,就能發世界上最難的郵件!"); // 郵件中的文本內容 MimeBodyPart mbpText = new MimeBodyPart(); mbpText.setContent("我是郵件的內容,可以顯示圖片哦!<img src='cdi:test.jpg'>", "text/html;charset=UTF-8"); // 郵件中的圖片 MimeBodyPart mbpImage = new MimeBodyPart(); DataHandler dhImage = new DataHandler(new FileDataSource("C:/test.jpg")); mbpImage.setDataHandler(dhImage); mbpImage.setContentID("test.jpg"); // 郵件中的附件 MimeBodyPart mbpAttmen = new MimeBodyPart(); DataHandler dhAttmen = new DataHandler(new FileDataSource("C:/test.txt")); mbpAttmen.setDataHandler(dhAttmen); // 郵件中在文本內容和附件路徑會出現中文亂碼,所以使用MimeUtility進行編碼。 mbpAttmen.setFileName(MimeUtility.encodeText(dhAttmen.getName())); // 將圖片與文本內容放到一個單元里 MimeMultipart mm1 = new MimeMultipart(); mm1.addBodyPart(mbpText); mm1.addBodyPart(mbpImage); // 描述正文和圖片的關系 mm1.setSubType("related"); // 返回需要將附加與文本和圖片添加到一個單元里。 // MimeMultipart不能添加MimeMultipart,但可以添加MimeBodyPart。 MimeBodyPart text_img = new MimeBodyPart(); text_img.setContent(mm1); // 將文本、圖片與附件添加到一個單元里 MimeMultipart mm2 = new MimeMultipart(); mm2.addBodyPart(mbpAttmen); mm2.addBodyPart(text_img); mm2.setSubType("mixed"); // 將內容添加到message中 message.setContent(mm2); message.saveChanges(); return message; } } |
參照上面的代碼,來看一下相關API的關系圖(老方的):

l MimeMessage類表示整封郵件。
l MimeBodyPart類表示郵件的一個MIME消息。
l MimeMultipart類表示由多個MIME消息組合成的一個組合MIME消息。
六、三大功能類
JavaMail API按其功能劃分通常可分為如下三大類:
l 創建和解析郵件內容:Message類是創建和解析郵件的核心API,它的實例對象代表一封電子郵件。
l 發送郵件:Transport類是發送郵件的核心API類,它的實例對象代表實現了某個郵件發送協議的郵件發送對象,例如SMTP協議。
l 接收郵件:Store類是接收郵件的核心API類,它的實例對象代表實現了某個郵件接收協議的郵件接收對象,例如POP3協議。
l Session類用于定義整個應用程序所需的環境信息,以及收集客戶端與郵件服務器建立網絡連接的會話信息,如郵件服務器的主機名、端口號、采用的郵件發送和接收協議等。Session對象根據這些信息構建用于郵件收發的Transport和Store對象,以及為客戶端創建Message對象時提供信息支持。
Ok了!今天下午的時候終于抽出點時間大家一起合個影。今天也是方老師最后一天的課程,大家都十分喜歡他,祝他身體健康,工作愉快!