本文提供的示例程序ListServer是一個簡單的郵件列表轉發服務器:它從指定帳號讀取新郵件并發送給所有訂閱者。Java Mail API不僅使得實現其基本功能相當簡單(使用缺省的POP3和SMTP),而且保證了程序易于支持任何可能遇到的系統環境。
運行該程序需要包含以下支持文件:Java Mail (mail.jar)、JAF(activation.jar)以及缺省的POP3支持(pop3.jar),如下面DOS批命令文件所示(這些JAR文件可以從Sun的Java Mail主頁下載,參見相關資源):
@echo off
PATH .;d:\jdk1.1\bin
set CLASSPATH=.;d:\jdk1.1\lib\classes.zip;activation.jar;mail.jar;pop3.jar
java ListServer %1 %2 %3 %4 %5 %6 %7 %8 %9
程序啟動后先由main()過程讀取命令行參數,如郵件服務器、郵件帳號、更新周期等。接下來創建ListServer實例,最后進入“讀取新郵件并轉發給訂閱者/等待直到下一次檢查時間到來”無限循環。ListServer的核心功能(即讀取和轉發所有新郵件)在process()過程實現,其主要操作過程為:
◆獲取javax.mail.Session實例,并進而獲得javax.mail.Store實例。
◆利用javax.mail.Store實例獲得缺省收件箱(INBOX)javax.mail.Folder實例。
◆使用javax.mail.Folder對象提取新郵件,存儲為javax.mail.Message對象數組。
◆創建javax.mail.FetchProfile以(潛在地)優化對特定郵件組成成分的提取。
請注意此處javax.mail.FetchProfile類的應用。FetchProfile類提供郵件協議提供者特有可選參數,其目的是更有效地實現郵件組成成分的預提取。Java Mail API鼓勵延遲提取郵件成分——即僅在真正需要的時候才提取。這不僅有利于改善系統的響應時間,某些操作(如顯示郵件標題列表)也能夠從中得到好處。下面代碼說明了FetchProfile的基本用法:
// 提取所有郵件的屬性和標記
Message[] messages = folder.getMessages();
FetchProfile fp = new FetchProfile();
fp.add(FetchProfile.Item.ENVELOPE);
fp.add(FetchProfile.Item.FLAGS);
fp.add("X-Mailer");
folder.fetch(messages, fp);
sendMsg()過程由processMsg()調用,負責分析指定收件并將它轉發給所有訂閱者。它首先獲得缺省Session實例,然后創建javax.mail.Transport對象發送消息:
// 設置屬性并獲得缺省進程實例
Properties props = new Properties();
props.put("mail.smtp.host", _smtpHost);
Session session = Session.getDefaultInstance(props, null);
......
// 發送消息
Transport transport = session.getTransport(SMTP_MAIL);
transport.connect(_smtpHost, _user, _password);
transport.sendMessage(newMessage, _toList);
郵件字段(如收件人、發件人、郵件主題和日期等)的設置方法如下:
// 創建新郵件 Address replyToList[] = { new InternetAddress(replyTo) };
Message newMessage = new MimeMessage(session);
if (_fromName != null)
newMessage.setFrom(new InternetAddress(from,
_fromName + " / " + replyTo));
else
newMessage.setFrom(new InternetAddress(from));
newMessage.setReplyTo(replyToList);
newMessage.setRecipients(Message.RecipientType.BCC, _toList);
newMessage.setSubject(subject);
newMessage.setSentDate(sentDate);
填寫郵件內容應該區分其類型(純文本和復合內容使用不同方法):
// 填寫郵件內容 Object content = message.getContent(); //原郵件內容
String debugText = "主題: " + subject + ", 發送日期: " + sentDate;
if (content instanceof Multipart)
{
debugMsg("轉發復合內容郵件 (" + debugText + ")");
newMessage.setContent((Multipart)message.getContent());
}
else
{
debugMsg("轉發純文本郵件 (" + debugText + ")");
newMessage.setText((String)content);
}
可以看到,javax.mail.internet.MimeMessage內容讀取例程getContent()只需要一次調用就可以讀取復雜的分級復合郵件。