隨筆-72  評論-63  文章-0  trackbacks-0
          ?第一件我們需要知道的事情是,通用電子郵件庫實際上是包裹在JavaMail外層的API,所以無論我們選擇哪種API,我們都需要JavaMail庫。您可能還需要JavaBeans激活框架(JavaBeans Activation Framework (JAF)),該框架將負責處理關于郵件選項的更復雜的內容。最后一個在“購物列表”上的就是通用電子郵件庫(Commons Email),您需要從JAF中將JavaMail庫中的mail.jar、JAF中的activation.jar和通用電子郵件庫中的commons-email-1.0.jar添加到classpath的設置中。

          ???? 我們現在已經擁有了支持部件的工具包,讓我們從使用JavaMail發送簡單的電子郵件開始講解,我們將提出所有的設置放到一個單獨的靜態類MailSettings當中,這樣做將在比較代碼的時候容易些。

          ???? 在發送電子郵件之前,您還需要知道SMTP服務器的主機名,SMTP服務器是負責將您的郵件發送到外部世界去的機器。

          ???? JavaMail使用了Session類的概念來保存諸如SMTP主機和認證的信息,主要想法是基于會話(Sessions)在Java虛擬機中可以被隔離,這可以阻止惡意代碼竊取其他用戶在其他會話中的信息,這些信息可能包括用戶名和密碼等認證信息。“但是”,您可能會說,“在同一時間,我只在Java 虛擬機上運行一個應用程序,而且我相信我的代碼。”JavaMail的目的是開發大型的郵件系統,它有一個具有復雜性的關聯層,您可以繞過沒有經驗的用戶,我們用以下的例子來說明:

          Properties props=new Properties();
          props.put("mail.smtp.host",MailSettings.smtpHost);
          Session session=Session.getDefaultInstance(props,null);

          ???? 此處,并沒有創建新的會話,您只是從會話工廠(session factory)中得到并通過Properties的實例來進行設置,我們只對SMTP主機進行了設置和傳送,在得到默認的實例的同時創建了一個共享的會話,現在我們可以使用這個會話來創建郵件消息了。

          Message message=new MimeMessage(session);

          ???? JavaMail中有一個Message類,各種各樣的消息都是它的子類,如果查看了JavaMail的API,您會發現它只有一個子類: MimeMessage。JavaMail是被設計為通用的電子郵件框架的,所以顯然存在冗余的抽象。總之,我們已經使用會話創建了一個 MimeMessage,現在我們需要來填充這個消息。

          message.setFrom(new InternetAddress (MailSettings.fromAddress, MailSettings.fromName));

          ???? 再次利用抽象,JavaMail有一個Address(地址)類,其他所有的地址類型皆源于此,但是我們現在只關心發送國際互聯網的電子郵件,所以我們制造一個InternetAddress,這個地址用來表示電子郵件的來源和一個用于顯示的“個人”名字。現自我們來設置郵件將發向何方。

          message.setRecipient(Message.RecipientType.TO, new InternetAddress(MailSettings.toAddress));

          ???? 地址的抽象將再次出現,我們設定接收器和接收器的類型,從此處開始,至少純文本的電子郵件可以穩定地傳送了,我們只需要設定郵件的標題、信文并打上時間戳。

          message.setSubject(MailSettings.messageSubject);
          message.setText(MailSettings.messageBody1);
          message.setSentDate(new Date());

          ???? 此時,我們已經準備好發送消息了。

          Transport.send(message);

          ???? 這個對Transport類的調用將會去查找適當的會話,并找出如何發送消息,盡管這樣做看上去有些不直觀。當我們完成這一步的時候,我們的郵件就已經發送出去了。此時,我們還需要添加代碼來捕獲三種JavaMail可能拋出的異常,它們是AddressException、 MessagingException和UnsupportedEncodingException. 但這就是最基本的使用JavaMail發送郵件的方法。

          ???? 現在,讓我們來看看如何使用Apache的通用電子郵件軟件包(參見MailCommons.java)來完成同樣的工作,通用電子郵件庫是一系列類的集合,它們基于您所要發送的郵件類型,其中最簡單的是SimpleEmail類,不需要建立任何會話或屬性列表:

          SimpleEmail email=new SimpleEmail();
          email.setHostName(MailSettings.smtpHost);

          ???? 以上代碼創建了我們的郵件并指定它通過我們選定的SMTP服務器發送,因為通用電子郵件庫只處理國際互聯網的電子郵件,所以就不必在創建InternetAddress實例上浪費時間了,我們可以簡單地設定來源地址:

          email.setFrom(MailSettings.fromAddress,MailSettings.fromName);

          ???? 我們只需要添加一個地址到收信人列表當中,而不是發送接收器的類型:

          email.addTo(MailSettings.toAddress);

          ???? 同樣,設定郵件的標題和信文與發送郵件都很簡單。

          email.setSubject(MailSettings.messageSubject);
          email.setMsg(MailSettings.messageBody1);
          email.send();

          ???? 我們所需要去捕獲的異常只有EmailException這一種,所以,您應該可以看出通過隱藏所有的框架和會話管理,事情變得非常簡單并且代碼更容易閱讀。

          ???? 當然,這是我們所能發送的最簡單的電子郵件,我們假設SMTP服務器不需要認證,我們發送的郵件只有一個收件人,并沒有發送郵件副本。讓我們先來看看認證,SMTP認證(SMTP AUTH)需要用戶名和密碼來發送郵件,在JavaMail中(參見MailJavaMail2.java),需要創建一個認證者(Authenticator)來返回所需的認證證書:

          class ForcedAuthenticator extends Authenticator {
          public PasswordAuthentication getPasswordAuthentication() {
          return new PasswordAuthentication(MailSettings.smtpUsername,
          MailSettings.smtpPassword);
          }
          }

          ???? 當我們創建會話的時候,就給出這個認證者的一個實例。

          Session session=Session.getDefaultInstance(props,new ForcedAuthenticator());

          ???? 然而,這里有一點要注意,這種做法將默認的會話綁定到了該認證者,因此您需要一個指向它的引用(reference)以再次取得這個會話。當然,您也可以轉而使用Session.getInstance(),來創建一個唯一的不共享的實例,但是這將依靠您自己來管理會話的實例。

          ???? 現在讓我們來看看如果使用通用電子郵件庫的方法來進行認證(參見MailCommons2.java),您將只看到一行新的語句:

          email.setAuthentication(MailSettings.smtpUsername,MailSettings.smtpPassword);這就解決了認證過程的所有痛苦。

          ???? 還有另外一種認證方式,那就是使用在郵件服務中的POP-before-SMTP,它并沒有實現SMTP AUTH,其實SMTP AUTH是SMTP之后的一種擴展,而POP-before-SMTP的工作方式則是將受密碼控制的郵件接收者和發送郵件的能力進行綁定,只有當用戶經過 POP協議訪問某個受密碼保護的POP郵件服務器一段時間之后,此用戶才能夠發送郵件。在JavaMail中,為了發送郵件,你需要編寫打開POP信箱的代碼,這將涉及JavaMail接收端的工作,我們將在下一篇文章中講解相關內容;而對于通用電子郵件庫來講,事情就容易得多了:

          email.setPopBeforeSMTP(true,popHost,popUsername,popPassword);

          ???? 這使您可以操作與POP-before-SMTP相關的所有功能,而根本不需要考慮處理與POP相關的工作。

          ???? 讓我們再來看看如何設定郵件的抄送收件人,現在JavaMail的Message類有一個setRecipients方法,該方法可以接受一個 InternetAddress的數組,但這樣做并不精巧,如果您已經有了一個儲存電子郵件地址的字符串數組,那就可以結束這種復雜方法的考驗。

          ArrayList ccs=new ArrayList();
          for(String s:MailSettings.ccAddresses) ccs.add(new InternetAddress(s));
          message.setRecipients(Message.RecipientType.CC,
          (InternetAddress[]) ccs.toArray(new InternetAddress[ccs.size()]));

          ???? 現在讓我們來看看通用電子郵件庫,我們發現了兩件事情:首先,setTo、setCc和setBcc方法都使用了InternetAddress的集合作為它們的參數,這樣做更符合Java的現行實踐;其次,addTo、addCc和addBcc方法將創建和添加收件人列表變得輕松。(參見 MailCommons3.java)

          for(String s:MailSettings.ccAddresses) email.addCc(s);

          ???? 這樣的代碼更加清晰。

          ???? 最后,讓我們來看看如何發送包含內嵌圖片的HTML格式的電子郵件,在此,JavaBeans激活框架將與JavaMail將協同工作,來協助圖片的編碼。在JavaMail的API中,我們首先創建一個MimeMultipart的實例,然后創建MimeBodyParts的實例,并將它們組裝到MimeMultipart的實例中,所以,嵌入單個圖片,比如uk-builder-com.gif這個圖片文件,并將它顯示在HTML消息中,我們需要完成以下步驟(參見HtmlJavaMail.java)

          MimeMultipart multipart=new MimeMultipart();
          BodyPart msgBodyPart=new MimeBodyPart();
          msgBodyPart.setContent("<H1>Hi! From HtmlJavaMail</H1>
          <img src=\"cid:logo\">","text/html");
          BodyPart embedImage=new MimeBodyPart();
          DataSource ds=new URLDataSource(new URL(MailSettings.inlineImage));
          embedImage.setDataHandler(new DataHandler(ds));
          embedImage.setHeader("Content-ID","");
          multipart.addBodyPart(msgBodyPart);
          multipart.addBodyPart(embedImage);
          message.setContent(multipart);

          ???? 第一個BodyPart將它的內容設置為一個字符串和“text/html”的內容類型,注意,在我們設置的HTML代碼中,IMG標簽指向了一個內容標識符(content-id),這就是MIME(多用途互聯網郵件擴充協議)消息部分的名稱,該消息將含有GIF格式的標識圖文件,為了嵌入這個圖片,我們創建了另一個BodyPart和一個JAF的數據源(data source),JAF類庫將負責管理內容的工作;然后我們將使用這個DataSource在BodyPart上添加一個DataHandler(數據處理器),這樣就可以讀出我們的URL所指向的內容了。最后,我們還要在BodyPart的頭部設定Content-ID,這樣它就可以作為內嵌圖片被訪問了。我們創建的那些BodyParts將被添加到MimeMultipart的實例中,為此,我們使用setContent()方法而不是調用 setText()方法。最棘手的部分莫過于管理這些內容標識符了,我們在此只完成了嵌入一個圖片的工作,但今后每添加一個圖片,您都需要在HTML中加入一個BodyPart和一個內容標識符。

          ???? 現在讓我們來看看使用通用電子郵件庫方法的版本(參見HtmlMailCommons.java):

          HtmlEmail email=new HtmlEmail();…
          String cid=email.embed(new URL(MailSettings.inlineImage),"Builder AU Logo");
          email.setHtmlMsg("<H1>Hi! From MailJavaMail3</H1><img src=\"cid:"+cid+"\">");
          email.setTextMsg("Your email client does not support HTML messages, sorry");

          ???? 這種方法簡短了很多,而且這一版本擁有更多的功能:當電子郵件客戶端不能處理HTML時,它將顯示備用的文字。我們從創建一個SimpleEmail實例改變為創建一個HtmlEmail實例。為了嵌入一個圖片,我們只需要簡單地調用HtmlEmail的嵌入方法,這將返回一個字符串,該字符串含有被生成和管理的內嵌圖片內容標識符的信息,我們可以直接使用這些信息來生成HTML內容。我們只需要簡單地對適當的字符串調用setHtmlMsg方法來進行設定,setTextMsg將設定不支持HTML的客戶端所顯示的文字,然后我們就可以發送郵件了。

          ???? 但是,到目前為止,您可能正在想“直接使用JavaMail的意義是什么呢?”答案是,如果您的目的是發送電子郵件,那么對于大多數情況,通用電子郵件庫僅僅需要少量的復雜代碼就可以完成您的需求,但是它連一點控制郵件會話和接收郵件的功能都沒有,如果您的應用軟件不需要大規模地進行郵件轉換或郵件閱讀的操作,那么應該不會造成不便。當然,如果您需要進行上述操作,那您就已經在使用JavaMail庫了。這里唯一的一個警告就是,在我寫這篇文章之時,通用電子郵件庫發布的是1.0版本,其API中可能有一些缺陷和漏洞,但它確實可以工作。現在您應該沒有借口不讓您的應用軟件在工作的時候發送狀態郵件了。

          這個例子不錯http://ldfren.bosinet.com/archives/76.html

          posted on 2006-05-15 14:20 船長 閱讀(647) 評論(0)  編輯  收藏

          只有注冊用戶登錄后才能發表評論。


          網站導航:
           
          主站蜘蛛池模板: 满洲里市| 太仆寺旗| 廉江市| 清河县| 平度市| 东乡族自治县| 榆林市| 商洛市| 太保市| 临潭县| 宣威市| 兖州市| 遂溪县| 阿拉善右旗| 怀宁县| 子洲县| 武陟县| 云和县| 碌曲县| 阿拉善右旗| 申扎县| 阿拉善盟| 防城港市| 凌源市| 怀化市| 清原| 仙居县| 醴陵市| 博客| 陈巴尔虎旗| 富顺县| 彩票| 佛冈县| 普兰县| 凤城市| 金坛市| 扶余县| 临汾市| 鹤庆县| 贵州省| 武陟县|