溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點擊 登錄注冊 即表示同意《億速云用戶服務條款》

如何使用JavaMail API

發布時間:2021-11-20 16:35:10 來源:億速云 閱讀:134 作者:柒染 欄目:編程語言

如何使用JavaMail API,很多新手對此不是很清楚,為了幫助大家解決這個難題,下面小編將為大家詳細講解,有這方面需求的人可以來學習下,希望你能有所收獲。

如何使用JavaMail API
本人將帶領大家學習一些使用Java Mail API任務案例。
1.發送郵件
在獲得了Session后,建立并填入郵件信息,然后發送它到郵件服務器。這便是使用Java Mail API發送郵件的過程,在發送郵件之前,我們需要設置SMTP服務器:通過設置Properties的mail.smtp.host屬性。

String host = ...;String from = ...;  String to = ...;// Get system propertiesProperties props = System.getProperties();  // Setup mail serverprops.put("mail.smtp.host", host);  // Get sessionSession session = Session.getDefaultInstance(props, null);  // Define messageMimeMessage message = new MimeMessage(session);  message.setFrom(new InternetAddress(from));  message.addRecipient(Message.RecipientType.TO,       new InternetAddress(to));message.setSubject("Hello JavaMail");  message.setText("Welcome to JavaMail");  // Send messageTransport.send(message);

由于建立郵件信息和發送郵件的過程中可能會拋出異常,所以我們需要將上面的代碼放入到try-catch結構塊中。

2.接收郵件
為了在讀取郵件,我們獲得了session,并且連接到了郵箱的相應store,打開相應的Folder,然后得到我們想要的郵件,當然別忘記了在結束時關閉連接。

String host = ...;String username = ...;  String password = ...;// Create empty propertiesProperties props = new Properties();  // Get sessionSession session = Session.getDefaultInstance(props, null);  // Get the storeStore store = session.getStore("pop3");store.connect(host, username, password);  // Get folderFolder folder = store.getFolder("INBOX");  folder.open(Folder.READ_ONLY);  // Get directoryMessage message[] = folder.getMessages();  for (int i=0, n=message.length;   i<N; I++) {     SYSTEM.OUT.PRINTLN(I + < SPAN>": " + message[i].getFrom()[0]        + "\t" + message[i].getSubject());}  // Close connection folder.close(false);  store.close();

上面的代碼所作的是從郵箱中讀取每個郵件,并且顯示郵件的發信人地址和主題。從技術角度講,這里存在著一個異常的可能:當發信人地址為空時,getFrom()[0]將拋出異常。

下面的代碼片斷有效的說明了如何讀取郵件內容,在顯示每個郵件發信人和主題后,將出現用戶提示從而得到用戶是否讀取該郵件的確認,如果輸入YES的話,我們可用Message.writeTo(java.io.OutputStream os)方法將郵件內容輸出到控制臺上,關于Message.writeTo()的具體用法請看JavaMail API。

BufferedReader reader = new BufferedReader (    new InputStreamReader(System.in));  // Get directoryMessage message[] = folder.getMessages();  for (int i=0, n=message.length; i<N; I++)  SPAN  <>{    System.out.println(i + ": " + message[i].getFrom()[0]         + "\t" + message[i].getSubject());      System.out.println("Do you want to read message? " +      "[YES to read/QUIT to end]");    String line = reader.readLine();      if ("YES".equals(line)) {      message[i].writeTo(System.out);    }   else if ("QUIT".equals(line)) {      break;    }}


3.刪除郵件和標志
設置與message相關的Flags是刪除郵件的常用方法。這些Flags表示了一些系統定義和用戶定義的不同狀態。在Flags類的內部類Flag中預定義了一些標志:

Flags.Flag.ANSWERED  Flags.Flag.DELETED  Flags.Flag.DRAFT  Flags.Flag.FLAGGED  Flags.Flag.RECENT  Flags.Flag.SEEN  Flags.Flag.USER

但需要在使用時注意的:標志存在并非意味著這個標志被所有的郵件服務器所支持。例如,對于刪除郵件的操作,POP協議不支持上面的任何一個。所以要確定哪些標志是被支持的——通過訪問一個已經打開的Folder對象的getPermanetFlags()方法,它將返回當前被支持的Flags類對象。
刪除郵件時,我們可以設置郵件的DELETED標志:

message.setFlag(Flags.Flag.DELETED, true);  但是首先要采用READ_WRITE的方式打開Folder:  folder.open(Folder.READ_WRITE);

在對郵件進行刪除操作后關閉Folder時,需要傳遞一個true作為對刪除郵件的擦除確認。

folder.close(true);

Folder類中另一種用于刪除郵件的方法expunge()也同樣可刪除郵件,但是它并不為sun提供的POP3實現支持,而其它第三方提供的POP3實現支持或者并不支持這種方法。
另外,介紹一種檢查某個標志是否被設置的方法:Message.isSet(Flags.Flag flag)方法,其中參數為被檢查的標志。

4.郵件認證
我們在前面已經學會了如何使用Authenticator類來代替直接使用用戶名和密碼這兩字符串作為Session.getDefaultInstance()或者Session.getInstance()方法的參數。在前面的小試牛刀后,現在我們將了解到全面認識一下郵件認證。
我們在此取代了直接使用郵件服務器主機名、用戶名、密碼這三個字符串作為連接到POP3 Store的方式,使用存儲了郵件服務器主機名信息的屬性文件,并在獲得Session時傳入自定義的Authenticator實例:

// Setup propertiesProperties props = System.getProperties();  props.put("mail.pop3.host", host);  // Setup authentication, get sessionAuthenticator auth = new PopupAuthenticator();  Session session = Session.getDefaultInstance(props, auth);  // Get the storeStore store = session.getStore("pop3");  store.connect();

PopupAuthenticator類繼承了抽象類Authenticator,并且通過重載Authenticator類的getPasswordAuthentication()方法返回PasswordAuthentication類對象。而getPasswordAuthentication()方法的參數param是以逗號分割的用戶名、密碼組成的字符串。

import javax.mail.*;  import java.util.*;  public class PopupAuthenticator extends Authenticator   {    public PasswordAuthentication getPasswordAuthentication(String param)   {      String username, password;        StringTokenizer st = new StringTokenizer(param, ",");        username = st.nextToken();        password = st.nextToken();        return new PasswordAuthentication(username, password);    }}


5.回復郵件
回復郵件的方法很簡單:使用Message類的reply()方法,通過配置回復郵件的收件人地址和主題(如果沒有提供主題的話,系統將默認將“Re:”作為郵件的主體),這里不需要設置任何的郵件內容,只要復制發信人或者reply-to到新的收件人。而reply()方法中的boolean參數表示是否將郵件回復給發送者(參數值為false),或是恢復給所有人(參數值為true)。
補充一下,reply-to地址需要在發信時使用setReplyTo()方法設置。

MimeMessage reply = (MimeMessage)message.reply(false);  reply.setFrom(new InternetAddress("president@whitehouse.gov"));  reply.setText("Thanks");  Transport.send(reply);

6.轉發郵件
轉發郵件的過程不如前面的回復郵件那樣簡單,它將建立一個轉發郵件,這并非一個方法就能做到。
每個郵件是由多個部分組成,每個部分稱為一個郵件體部分,是一個BodyPart類對象,對于MIME類型郵件來講就是MimeBodyPart類對象。這些郵件體包含在成為Multipart的容器中對于MIME類型郵件來講就是MimeMultiPart類對象。在轉發郵件時,我們建立一個文字郵件體部分和一個被轉發的文字郵件體部分,然后將這兩個郵件體放到一個Multipart中。說明一下,復制一個郵件內容到另一個郵件的方法是僅復制它的DataHandler(數據處理者)即可。這是由JavaBeans Activation Framework定義的一個類,它提供了對郵件內容的操作命令的訪問、管理了郵件內容操作,是不同的數據源和數據格式之間的一致性接口。

// Create the message to forwardMessage forward = new MimeMessage(session);  // Fill in headerforward.setSubject("Fwd: " + message.getSubject());  forward.setFrom(new InternetAddress(from));  forward.addRecipient(Message.RecipientType.TO,     new InternetAddress(to));  // Create your new message partBodyPart messageBodyPart = new MimeBodyPart();messageBodyPart.setText(    "Here you go with the original message:\n\n");  // Create a multi-part to combine the partsMultipart multipart = new MimeMultipart();  multipart.addBodyPart(messageBodyPart);  // Create and fill part for the forwarded contentmessageBodyPart = new MimeBodyPart();  messageBodyPart.setDataHandler(message.getDataHandler());  // Add part to multi partmultipart.addBodyPart(messageBodyPart);  // Associate multi-part with messageforward.setContent(multipart);  // Send messageTransport.send(forward);

7.使用附件
附件作為與郵件相關的資源經常以文本、表格、圖片等格式出現,如流行的郵件客戶端一樣,我們可以用JavaMail API從郵件中獲取附件或是發送帶有附件的郵件。

A.發送帶有附件的郵件
發送帶有附件的郵件的過程有些類似轉發郵件,我們需要建立一個完整郵件的各個郵件體部分,在第一個部分(即我們的郵件內容文字)后,增加一個具有DataHandler的附件而不是在轉發郵件時那樣復制第一個部分的DataHandler。

如果我們將文件作為附件發送,那么要建立FileDataSource類型的對象作為附件數據源;如果從URL讀取數據作為附件發送,那么將要建立URLDataSource類型的對象作為附件數據源。

然后將這個數據源(FileDataSource或是URLDataSource)對象作為DataHandler類構造方法的參數傳入,從而建立一個DataHandler對象作為數據源的DataHandler。

接著將這個DataHandler設置為郵件體部分的DataHandler。這樣就完成了郵件體與附件之間的關聯工作,下面的工作就是BodyPart的setFileName()方法設置附件名為原文件名。

最后將兩個郵件體放入到Multipart中,設置郵件內容為這個容器Multipart,發送郵件。

// Define messageMessage message = new MimeMessage(session);  message.setFrom(new InternetAddress(from));  message.addRecipient(Message.RecipientType.TO,       new InternetAddress(to));message.setSubject("Hello JavaMail Attachment");  // Create the message part BodyPart messageBodyPart = new MimeBodyPart();  // Fill the messagemessageBodyPart.setText("Pardon Ideas");  Multipart multipart = new MimeMultipart();  multipart.addBodyPart(messageBodyPart);  // Part two is attachmentmessageBodyPart = new MimeBodyPart();  DataSource source = new FileDataSource(filename);  messageBodyPart.setDataHandler(new DataHandler(source));  messageBodyPart.setFileName(filename);multipart.addBodyPart(messageBodyPart);  // Put parts in messagemessage.setContent(multipart);  // Send the messageTransport.send(message);

如果我們使用servlet實現發送帶有附件的郵件,則必須上傳附件給servlet,這時需要注意提交頁面form中對編碼類型的設置應為multipart/form-data。

<FORM encType=multipart/form-data       
method=post action="/myservlet">    

B.讀取郵件中的附件
讀取郵件中的附件的過程要比發送它的過程復雜一點。因為帶有附件的郵件是多部分組成的,我們必須處理每一個部分獲得郵件的內容和附件。
但是如何辨別郵件信息內容和附件呢?Sun在Part類(BodyPart類實現的接口類)中提供了getDisposition()方法讓開發者獲得郵件體部分的部署類型,當該部分是附件時,其返回之將是Part.ATTACHMENT。但附件也可以沒有部署類型的方式存在或者部署類型為Part.INLINE,無論部署類型為Part.ATTACHMENT還是Part.INLINE,我們都能把該郵件體部分導出保存。

Multipart mp = (Multipart)message.getContent();  for (int i=0, n=multipart.getCount(); i{    Part part = multipart.getBodyPart(i));      String disposition = part.getDisposition();      if ((disposition != null) &&           ((disposition.equals(Part.ATTACHMENT) ||            (disposition.equals(Part.INLINE)))   { saveFile(part.getFileName(), part.getInputStream());    }}

下列代碼中使用了saveFile方法是自定義的方法,它根據附件的文件名建立一個文件,如果本地磁盤上存在名為附件的文件,那么將在文件名后增加數字表示區別。然后從郵件體中讀取數據寫入到本地文件中(代碼省略)。

// from saveFile()File file = new File(filename);  for (int i=0; file.exists(); i++)   {    file = new File(filename+i);}

以上是郵件體部分被正確設置的簡單例子,如果郵件體部分的部署類型為null,那么我們通過獲得郵件體部分的MIME類型來判斷其類型作相應的處理,代碼結構框架如下:

if (disposition == null)   {    // Check if plain    MimeBodyPart mbp = (MimeBodyPart)part;      if (mbp.isMimeType("text/plain"))   {      // Handle plain    } else   {      // Special non-attachment cases here of         // image/gif, text/html, ...    }...}

8.處理HTML郵件
前面的例子中發送的郵件都是以文本為內容的(除了附件),下面將介紹如何接收和發送基于HTML的郵件。
A.發送HTML郵件
假如我們需要發送一個HTML文件作為郵件內容,并使郵件客戶端在讀取郵件時獲取相關的圖片或者文字的話,只要設置郵件內容為html代碼,并設置內容類型為text/html即可:

  1. String htmlText = "

    Hello

    " + ";  


  2. message.setContent(htmlText, "text/html")); 

請注意:這里的圖片并不是在郵件中內嵌的,而是在URL中定義的。郵件接收者只有在線時才能看到。
在接收郵件時,如果我們使用JavaMail API接收郵件的話是無法實現以HTML方式顯示郵件內容的。因為JavaMail API郵件內容視為二進制流。所以要顯示HTML內容的郵件,我們必須使用JEditorPane或者第三方HTML展現組件。

以下代碼顯示了如何使用JEditorPane顯示郵件內容:

if (message.getContentType().equals("text/html"))   {    String content = (String)message.getContent();      JFrame frame = new JFrame();      JEditorPane text = new JEditorPane("text/html", content);      text.setEditable(false);      JScrollPane pane = new JScrollPane(text);      frame.getContentPane().add(pane);      frame.setSize(300, 300);      frame.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);      frame.show();}

B.在郵件中包含圖片
如果我們在郵件中使用HTML作為內容,那么最好將HTML中使用的圖片作為郵件的一部分,這樣無論是否在線都會正確的顯示HTML中的圖片。處理方法就是將HTML中用到的圖片作為郵件附件并使用特殊的cid URL作為圖片的引用,這個cid就是對圖片附件的Content-ID頭的引用。
處理內嵌圖片就像向郵件中添加附件一樣,不同之處在于我們必須通過設置圖片附件所在的郵件體部分的header中Content-ID為一個隨機字符串,并在HTML中img的src標記中設置為該字符串。這樣就完成了圖片附件與HTML的關聯。

  1. String file = ...;  

  2. // Create the messageMessage message = new MimeMessage(session);  

  3. // Fill its headersmessage.setSubject("Embedded Image");  

  4. message.setFrom(new InternetAddress(from));  

  5. message.addRecipient(Message.RecipientType.TO,       

  6. new InternetAddress(to));  

  7. // Create your new message partBodyPart messageBodyPart = new MimeBodyPart();  

  8. String htmlText = "

    Hello

    " + ";


  9. messageBodyPart.setContent(htmlText, "text/html");  

  10. // Create a related multi-part to combine the partsMimeMultipart multipart = new MimeMultipart("related");

  11. multipart.addBodyPart(messageBodyPart);  

  12. // Create part for the imagemessageBodyPart = new MimeBodyPart();  

  13. // Fetch the image and associate to partDataSource fds = new FileDataSource(file);  

  14. messageBodyPart.setDataHandler(new DataHandler(fds));  

  15. messageBodyPart.setHeader("Content-ID","");  

  16. // Add part to multi-partmultipart.addBodyPart(messageBodyPart);  

  17. // Associate multi-part with messagemessage.setContent(multipart); 


9.在郵件中搜索短語
JavaMail API提供了過濾器機制,它被用來建立搜索短語。這個短語由javax.mail.search包中的SearchTerm抽象類來定義,在定義后我們便可以使用Folder的Search()方法在Folder中查找郵件:

SearchTerm st = ...;Message[] msgs = folder.search(st);

下面有22個不同的類(繼承了SearchTerm類)供我們使用:

AND terms (class AndTerm)  OR terms (class OrTerm)  NOT terms (class NotTerm)  SENT DATE terms (class SentDateTerm)  CONTENT terms (class BodyTerm)  HEADER terms (FromTerm / FromStringTerm, RecipientTerm / RecipientStringTerm, SubjectTerm, etc.)

使用這些類定義的斷語集合,我們可以構造一個邏輯表達式,并在Folder中進行搜索。下面是一個實例:在Folder中搜索郵件主題含有“ADV”字符串或者發信人地址為friend@public.com的郵件。

SearchTerm st =     new OrTerm(      new SubjectTerm("ADV:"),         new FromStringTerm("friend@public.com"));  Message[] msgs = folder.search(st);

看完上述內容是否對您有幫助呢?如果還想對相關知識有進一步的了解或閱讀更多相關文章,請關注億速云行業資訊頻道,感謝您對億速云的支持。

向AI問一下細節

免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。

AI

亚洲午夜精品一区二区_中文无码日韩欧免_久久香蕉精品视频_欧美主播一区二区三区美女