JavaMail 深入淺出(轉(zhuǎn))

           我干軟件開發(fā)也有一點的年頭了,回頭想想,也經(jīng)歷了不少的酸甜苦辣,為解決了復(fù)雜的問題快樂過.也為不分晝夜的加班趕工程郁悶過.不過這些都沒能減少我對計算機的熱情,我對程序的喜好.以前對JavaMail也有一些學(xué)習(xí)性的認(rèn)識,不過一直沒在實際的項目中應(yīng)用過.直到最近的一個項目,需要JavaMail 所以我打算認(rèn)真的學(xué)習(xí)一下這種技術(shù),因為我目前擅長的是Struts,而Struts又不具備郵件發(fā)送的功能,所以我要深刻的學(xué)習(xí)一下 JavaMailAPI.所以在我學(xué)會了JavaMail的基本操作的同時也將這篇文章獻(xiàn)給大家,雖然技術(shù)含量不高,但是希望能對一些剛剛接觸 JavaMail的同道中人有所幫助.好了閑話少說進(jìn)入正題,首先介紹幾個郵件傳輸協(xié)議,雖然說不了解這些協(xié)議也可以實用JavaMailAPI,但是我始終認(rèn)為,如果不透徹的了解一種技術(shù)的本質(zhì),即使會用了也是照葫蘆畫瓢,換一種模式也許就玩不轉(zhuǎn)了.


              SMTP: 簡單郵件傳輸協(xié)議(Simple Mail Transfer Protocol,SMTP)由RFC821定義,它定義了發(fā)送郵件的機制,在JavaMail環(huán)境中,基于JavaMail的程序?qū)⒑鸵蛱鼐W(wǎng)服務(wù)供應(yīng)商 ISP(internet Service Provider ’ s)SMTP服務(wù)器通信.SMTP服務(wù)器會中轉(zhuǎn)消息給接收方SMTP服務(wù)器以便最終讓用戶經(jīng)由POP或者IMAP獲得.

              POP: 代表郵局協(xié)議(Post Office Protocol).目前的版本是3.所以一般都稱之為POP3.這個協(xié)議是由RFC1939定義的.POP是一種機制,因特網(wǎng)上多大數(shù)用戶用它得到郵件.它規(guī)定每個用戶一個郵箱的支持.使用POP協(xié)議的時候,用戶的許多性能并不是由POP協(xié)議支持的,如查看幾封新郵件消息這個功能,這些功能內(nèi)建在如 Eudora或MicrosoftOutlook之類的程序中,它們記住一些事.所以在用JavaMail的時候,如果你想要這些信息,你就必須自己算了.

              IMAP: 是更高級的用戶接收消息的協(xié)議,被定義在RFC2060中,IMAP代表因特網(wǎng)消息訪問協(xié)議(Internet Message Access Protocol),目前用的版本是4,所以也叫做IMAP4.在用到IMAP的時候,郵件服務(wù)器必須支持這個協(xié)議,不能僅僅把使用POP的程序用于 IMAP,并指望它支持IMAP所有性能.

              MIME:是因特網(wǎng)郵件擴(kuò)展標(biāo)準(zhǔn)(Multipurpose Internet Mail Extensions).它不是郵件傳輸協(xié)議,但是對于傳輸?shù)膬?nèi)容的消息,附件以及其他的內(nèi)容定義了格式.可以理解成一個定義合適的標(biāo)準(zhǔn).

               NNTP:因為JavaMail將供應(yīng)商和所有其它的東西分開了,您就能輕松添加額外的協(xié)議支持.NNTP 就是網(wǎng)絡(luò)新聞傳輸協(xié)議.

              JavaMailAPI可以到 http://java.sun.com/products/javamail/index.html 進(jìn)行下載,并將mail.jar添加到classpath即可.

              JAF框架可以到 http://java.sun.com/products/javabeans/glasgow/jaf.html 進(jìn)行下載,并將activation.jar添加到classpath即可.



              如果實用J2EE就沒由什么特定非要用基本的JavaMailAPI了.J2EE的類就能處理了.只要確保j2ee.jar文件在classpath中就Ok了.

          下面我用一個最簡單的例子還演示第一條消息的發(fā)送.

          1,獲取系統(tǒng)Properties.

          Properties props = System.getProperties();

          2,將您的SMTP服務(wù)器名添加到mail.smtp.host關(guān)鍵字的屬性中.

          Props.pout( “ mail.smtp.host ” ,host);

          3,獲取基于Properties Session對象.

          Session session = Session.getDefaultInstance(props,null);

          4,從Session創(chuàng)建一個MimeMessage.

          MimeMessage message = new MimeMessage(session);

          5,設(shè)置消息from域.

          Message.setForm(new InternetAddress(from));

          6,設(shè)置to域.

          Message.addRecipient(Message.RecipientType.TO,new InternetAddress(to));

          7,設(shè)置消息主題.

          message.setSubject( “ HelloJavaMail ” );

          8,設(shè)置消息內(nèi)容.

          Message.setText( “ Welcome to JavaMail ” );

          9發(fā)送消息.

          Transport.send(message);

          10,在編譯用運的時候傳遞MSTP服務(wù)器,from地址,to地址.

              通過簡單的接觸了JavaMail相信大家多郵件發(fā)送也有了簡單的了解和認(rèn)識,下面我主要研究一下它的具體功能,也就是說具體的接口或類的含義.

              Session 類定義了一個基本的郵件會話,所有的其他類都是由這個session才得意生效的,Session對象用java.util.Properties對象獲取信息,如郵件服務(wù)器,用戶名,密碼及整個應(yīng)用程序中共享的其他信息.類的構(gòu)造器是此有的,private.它能用 getDefaultInstance()方法來共享.獲取Session對象的方方法如下:

          Properties props = new Properties();

          Session session = Session.getDefaultInstance(props,null);

          Null參數(shù)都是Authenticator對象,在這里沒有使用.

          對于大多數(shù)情況,共享的session已經(jīng)足夠用了.

              Message 消息類,在獲得了Session對象后,就可以繼續(xù)創(chuàng)建要發(fā)送的消息.因為Message是個抽象類,您必須用一個子類,多數(shù)情況下為 java.mail.internet.MimeMessage.這個能理解成MIME類型和頭的電子郵件消息.正如不同的RFC中定義的,雖然在某些頭部域非ASCII字符也能被編譯,但是Message頭只能被限制用US-ASCII字符.要創(chuàng)建一個Message請將Session對象傳遞給 MimeMessage的構(gòu)造器.

          MimeMessage message = newMimeMessage(session);

          一旦獲得消息,就可以設(shè)置各個部分了.最基本的就是setContent()方法,例如/

          message.setContent( “ Hello ” , ” text/plain ” );

          如果知道在實用MimeMessage,而且消息是純文本格式,就可以用setText()方法,它只需要代表實際內(nèi)容的參數(shù).(Mime類型缺省為text/plain)

          用setSubject()方法設(shè)置subject(主題);

          message.setSubject( “ 主題 ” );

              Address地址類,和Message一樣也是一個抽象類,一旦創(chuàng)建了Session和Message并將內(nèi)容填入消息后,就可以用Address確定信件的地址了,用javax.mail.internet.

          InternetAddress類.若創(chuàng)建的地址只包含電子郵件地址,只要傳遞電子郵件地址給構(gòu)造器就可以了.例如:Address address = new InternetAddress( “ it5719@163.com ” );

          若希望名字挨著電子郵件現(xiàn)實,就可以把它傳遞給構(gòu)造器,如下:

          Address address = new InternetAddress( “ it5719@163.com ” , ” 我心依舊 ” );

          需要為消息的from 域和to域創(chuàng)建地址對象,除非郵件服務(wù)器阻止,沒有什么能阻止你發(fā)送一段看上去是任何人的消息了呵呵.一旦創(chuàng)建address將他們域消息連接方法有兩種,如要要識別發(fā)件人的就可以用setFrom()和setReplyTo方法.然后message.setFrom(address);

          需要實用多個from地址的就用addFrom()方法.例子如下:

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

          若要識別消息recipient收件人,就要實用addRecipient()方法了.例如:

          message.addRecipient(type,address)

              Authenticator 與java.net類一樣,JavaMailAPI也可以利用Authentcator通過用戶名密碼訪問受保護(hù)的資源.對于JavaMail來說,這些資源就是郵件服務(wù)器,Authentcator類在javax.mail包中.要使用Authenticator,首先創(chuàng)建一個抽象的子類,并從

          GetPasswordAuthentication 方法中返回passwordAuthentication實例,創(chuàng)建完成后,您必須向session注冊Authenticator,然后在需要認(rèn)證的時候會通知它,其實說白了就是把配置的用戶名和密碼返回給調(diào)用它的程序.例如:

          Properties props = new properties();

          Authenticator auth = new MailAuthenticator()//接口聲明,創(chuàng)建自己新類的實例.

          Session session = Session.getDefauItInstance(props,auth);

              Transport消息發(fā)送傳輸類,這個類用協(xié)議指定的語言發(fā)送消息,通常是SMTP,它是抽象類,它的工作方式與Session有些類似,盡調(diào)用靜態(tài)方法send()方法,就OK了.例如:

          Transport.send(message);

          或者也可以從針對協(xié)議的會話中獲取一個特定的實例,傳遞用戶名和密碼.發(fā)送消息,然后關(guān)閉連接,例如:

          message.saveChanges();

          transport transport = session.getTreansport( “ smtp ” );//指定的協(xié)議

          transport.connect(host,username,password);

          transport.sendMessage(message,message.getAllRecipients());

          transport.close();

          如果要觀察傳到郵件服務(wù)器上的郵件命令,請用session.setDubug(true)設(shè)置調(diào)試標(biāo)志.

              Store和folder用session獲取消息,與發(fā)送消息開始很相似,但是在session得到后,很可能實用用戶名和密碼或?qū)嵱肁uthenticator連接到一個Store.類似于Transport,也是一樣要告訴store用什么協(xié)議.例如

          Store store = session.getStore( “ pop3 ” );

          Store.connect(host,username,password);

          連接到Store之后,接下來,獲得一個folder,必須打開它就可以讀取里邊的消息了.

          Folder folder = store.getFolder("INBOX");

          folder.open(Folder.READ_ONLY);

          Message[] message = folder.getMessages();

          POP3唯一可用的文件夾就是INBOX,如果實用IMAP,還可以用其他的文件夾.

          當(dāng)讀到了具體的message以后,就可以用getContent來獲取內(nèi)容,或者用writeTo()將內(nèi)容寫入流,getContent()方法只能得到消息內(nèi)容,而writeTo()的輸出卻包含消息頭.

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

          一旦讀取完畢郵件,要關(guān)閉store和folder的連接.

          folder.colse(boolean);

          store.colse();

          傳遞給folder的close()方法的boolean參數(shù)表示是否清楚已刪除的消息從而更新folder.

              上面就是JavaMail郵件操作的基本的常用類,我覺得理解了這幾個類的機制,基本就可以處理一般的郵件操作了.下面是一個我寫的JavaMail實現(xiàn)郵件發(fā)送的代碼.

          首先是一個Authenticator類的實現(xiàn):記錄用戶名和密碼:

          import javax.mail.*;

           

           

          public class MailAuthenticator extends Authenticator

          {

              //******************************

              //由于發(fā)送郵件的地方比較多,

              //下面統(tǒng)一定義用戶名,口令.

              //******************************

              public static String HUAWEI_MAIL_USER = "it5719@163.com";

              public static String HUAWEI_MAIL_PASSWORD = "密碼";

           

           

              public MailAuthenticator()

              {

              }

           

              protected PasswordAuthentication getPasswordAuthentication()

              {

                  return new PasswordAuthentication(HUAWEI_MAIL_USER, HUAWEI_MAIL_PASSWORD);

              }

           

          }

           

          這個類是發(fā)送郵件的類.

           

           

          package com.deepdo.common.mail;

           

          /**

           * 此處插入類型說明。

           * 創(chuàng)建日期:(2006-4-21 14:57:16)

           * @author:張宏亮

           */

           

          import java.util.*;

          import java.io.*;

          import javax.mail.*;

          import javax.mail.internet.*;

          import javax.activation.*;

           

           

          public class SendMail {

           

              //要發(fā)送Mail地址

              private String mailTo = null;

              //Mail發(fā)送的起始地址

              private String mailFrom = null;

              //SMTP主機地址

              private String smtpHost = null;

              //是否采用調(diào)試方式

              private boolean debug = false;

           

              private String messageBasePath = null;

              //Mail主題

              private String subject;

              //Mail內(nèi)容

              private String msgContent;

           

              private Vector attachedFileList;

              private String mailAccount = null;

              private String mailPass = null;

              private String messageContentMimeType ="text/html; charset=gb2312";

           

              private String mailbccTo = null;

              private String mailccTo = null;

              /**

               * SendMailService 構(gòu)造子注解。

               */

              public SendMail() {

                  super();

            

              }

           

              private void fillMail(Session session,MimeMessage msg) throws IOException, MessagingException{

            

                  String fileName = null;

                  Multipart mPart = new MimeMultipart();

                  if (mailFrom != null) {

                      msg.setFrom(new InternetAddress(mailFrom));

                      System.out.println("發(fā)送人Mail地址:"+mailFrom);

                  } else {

                      System.out.println("沒有指定發(fā)送人郵件地址!");

                      return;

                  }

                  if (mailTo != null) {

                      InternetAddress[] address = InternetAddress.parse(mailTo);

                      msg.setRecipients(Message.RecipientType.TO, address);

                      System.out.println("收件人Mail地址:"+mailTo);

                  } else {

                      System.out.println("沒有指定收件人郵件地址!");

                      return;

                  }

            

                  if (mailccTo != null) {

                      InternetAddress[] ccaddress = InternetAddress.parse(mailccTo);

                      System.out.println("CCMail地址:"+mailccTo);

                      msg.setRecipients(Message.RecipientType.CC, ccaddress);

                  }

                  if (mailbccTo != null) {

                      InternetAddress[] bccaddress = InternetAddress.parse(mailbccTo);

                      System.out.println("BCCMail地址:"+mailbccTo);

                      msg.setRecipients(Message.RecipientType.BCC, bccaddress);

                  }

                  msg.setSubject(subject);

                  InternetAddress[] replyAddress = { new InternetAddress(mailFrom)};

                  msg.setReplyTo(replyAddress);

                  // create and fill the first message part

                  MimeBodyPart mBodyContent = new MimeBodyPart();

                  if (msgContent != null)

                      mBodyContent.setContent(msgContent, messageContentMimeType);

                  else

                      mBodyContent.setContent("", messageContentMimeType);

                  mPart.addBodyPart(mBodyContent);

                  // attach the file to the message

                  if (attachedFileList != null) {

                      for (Enumeration fileList = attachedFileList.elements(); fileList.hasMoreElements();) {

                          fileName = (String) fileList.nextElement();

                          MimeBodyPart mBodyPart = new MimeBodyPart();

            

                          // attach the file to the message

                          FileDataSource fds = new FileDataSource(messageBasePath + fileName);

                          System.out.println("Mail發(fā)送的附件為:"+messageBasePath + fileName);

                          mBodyPart.setDataHandler(new DataHandler(fds));

                          mBodyPart.setFileName(fileName);

                          mPart.addBodyPart(mBodyPart);

                      }

                  }

                  msg.setContent(mPart);

                  msg.setSentDate(new Date());

              }

              /**

               * 此處插入方法說明。

               */

              public void init()

              {

            

              }

              /**

               * 發(fā)送e_mail,返回類型為int

               * 當(dāng)返回值為0時,說明郵件發(fā)送成功

               * 當(dāng)返回值為3時,說明郵件發(fā)送失敗

               */

              public int sendMail() throws IOException, MessagingException {

            

                  int loopCount;

                  Properties props = System.getProperties();

                  props.put("mail.smtp.host", smtpHost);

                  props.put("mail.smtp.auth", "true");

            

                  MailAuthenticator auth = new MailAuthenticator();

            

                  Session session = Session.getInstance(props, auth);

                  session.setDebug(debug);

                  MimeMessage msg = new MimeMessage(session);

                  Transport trans = null;

                  try {

            

                      fillMail(session,msg);

                      // send the message

                      trans = session.getTransport("smtp");

                      try {

                          trans.connect(smtpHost, MailAuthenticator.HUAWEI_MAIL_USER, MailAuthenticator.HUAWEI_MAIL_PASSWORD);//, HUAWEI_MAIL_PASSWORD);

                      } catch (AuthenticationFailedException e) {

                          e.printStackTrace();

                          System.out.println("連接郵件服務(wù)器錯誤:");

                          return 3;

                      } catch (MessagingException e) {

                          System.out.println("連接郵件服務(wù)器錯誤:");

                          return 3;

                      }

            

                      trans.send(msg);

                      trans.close();

            

                  } catch (MessagingException mex) {

                      System.out.println("發(fā)送郵件失敗:");

                      mex.printStackTrace();

                      Exception ex = null;

                      if ((ex = mex.getNextException()) != null) {

                          System.out.println(ex.toString());

                          ex.printStackTrace();

                      }

                      return 3;

                  } finally {

                      try {

                          if (trans != null && trans.isConnected())

                              trans.close();

                      } catch (Exception e) {

                          System.out.println(e.toString());

                      }

                  }

                  System.out.println("發(fā)送郵件成功!");

                  return 0;

              }

              public void setAttachedFileList(java.util.Vector filelist)

              {

                  attachedFileList = filelist;

              }

              public void setDebug(boolean debugFlag)

              {

                  debug=debugFlag;

              }

              public void setMailAccount(String strAccount) {

                  mailAccount = strAccount;

              }

              public void setMailbccTo(String bccto) {

                  mailbccTo = bccto;

              }

              public void setMailccTo(String ccto) {

                  mailccTo = ccto;

              }

              public void setMailFrom(String from)

              {

                  mailFrom=from;

              }

              public void setMailPass(String strMailPass) {

                  mailPass = strMailPass;

              }

              public void setMailTo(String to)

              {

                  mailTo=to;

              }

              public void setMessageBasePath(String basePath)

              {

                  messageBasePath=basePath;

              }

              public void setMessageContentMimeType(String mimeType)

              {

                  messageContentMimeType = mimeType;

              }

              public void setMsgContent(String content)

              {

                  msgContent=content;

              }

              public void setSMTPHost(String host)

              {

                  smtpHost=host;

              }

              public void setSubject(String sub)

              {

                  subject=sub;

              }

            

              public static void main(String[] argv) throws Exception

              {

                  for(int i = 0;i<10;i++) {

                  SendMail sm = new SendMail();

                  sm.setSMTPHost("SMTP地址");

                  sm.setMailFrom("發(fā)送地址");

                  sm.setMailTo("目標(biāo)地址");

                  sm.setMsgContent("內(nèi)容");

                  sm.setSubject("標(biāo)題");

                  sm.sendMail();

                  }

              }

          }

          posted on 2009-06-16 14:44 MichaelLee 閱讀(126) 評論(0)  編輯  收藏


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


          網(wǎng)站導(dǎo)航:
           
          <2025年5月>
          27282930123
          45678910
          11121314151617
          18192021222324
          25262728293031
          1234567

          導(dǎo)航

          統(tǒng)計

          公告

          ====Michael Lee====
          =Java Sofware Engineer=
          =Work @ Beijing=
          ---再煩,也別忘微笑;再急,也要注意語氣;再苦,也別忘堅持;再累,也要愛自己!---
          ---低調(diào)做人,你會一次比一次穩(wěn)健;高調(diào)做事,你會一次比一次優(yōu)秀---
          ---成功的時候不要忘記過去;失敗的時候不要忘記還有未來---

          常用鏈接

          留言簿(2)

          隨筆分類

          隨筆檔案

          文章分類

          文章檔案

          搜索

          最新評論

          閱讀排行榜

          評論排行榜

          主站蜘蛛池模板: 方正县| 咸阳市| 太谷县| 龙江县| 富顺县| 辽宁省| 广汉市| 新龙县| 奇台县| 龙山县| 马关县| 德州市| 额济纳旗| 敖汉旗| 沙坪坝区| 沁阳市| 新宾| 封丘县| 保山市| 文成县| 梁平县| 宁夏| 井研县| 绍兴县| 琼海市| 繁峙县| 东宁县| 定陶县| 淮滨县| 安仁县| 德阳市| 祁阳县| 繁昌县| 巴彦县| 科技| 铜川市| 濮阳县| 高阳县| 西吉县| 青岛市| 卢龙县|