javaMail應(yīng)用
JavaMail API是讀取、撰寫、發(fā)送電子信息的可選包。 一、環(huán)境配置: 為了運行Javamail。我們需要在classpath里導(dǎo)入兩個包:mail.jar和activation.jar, mail.jar實現(xiàn)提供了對SMTP、IMAP4、POP3的支持,activation.jar增加了對任何數(shù)據(jù)塊的分類、以及對它們的處理的特性。這些特性是JavaMail API需要的 為了要發(fā)送郵件和接收郵件,我們必須要遵守smtp和pop3協(xié)議,不過還有其它協(xié)議也可執(zhí)行(如IMAP)。如果把本機(jī)當(dāng)作服務(wù)器來發(fā)送郵件可在http://jakrata.網(wǎng)站里下載james郵件服務(wù)器,然后解壓在本機(jī)上。運行james/bin里的run.bat就可以啟動了服務(wù)器。 在DOS里登錄郵件服務(wù)器命令為:telnet localhost 4555 增加郵箱用戶名命令為:adduser 用戶名 密碼 如:adduser fyc fyc 就建立了這樣一個郵箱fyc@localhost 密碼為:fyc 如果想要更多功能用help命令。 注意:如果在本機(jī)裝了郵件服務(wù)器的話,只能在本機(jī)局域網(wǎng)里申請郵箱,發(fā)送和接收。不能發(fā)送到外部的郵箱里去。如果用外部的郵件服務(wù)器像比如163的服務(wù)器等就可以隨心所欲的發(fā)郵件了。 二、相關(guān)協(xié)議介紹: 常用到的協(xié)議為SMTP、POP、MIME、IMAP,雖然JavaMail API是被設(shè)計為與協(xié)議無關(guān)的,但如果我們使用的功能并不被我們選擇的協(xié)議支持,那么JavaMail API就不可能發(fā)揮它提功能。 1.SMTP 簡單郵件傳輸協(xié)議定義了遞送郵件的機(jī)制。我們將使用基于Java-Mail的程序與公司或者ISP的SMTP服務(wù)器進(jìn)行通訊。這個SMTP服務(wù)器將郵件轉(zhuǎn)發(fā)到接收者的SMTP服務(wù)器,直至最后被接收者通過POP或者IMAP協(xié)議獲取。 2.POP POP是一種郵局協(xié)議,目前為第3個版本,即POP3。POP定義了一種用戶如何獲得郵件的機(jī)制。它規(guī)定了每個用戶使用一個單獨的郵箱。 3.MIME MIME并不是用于傳送郵件的協(xié)議,它作為多用途郵件的擴(kuò)展定義了郵件內(nèi)容的格式:信息格式、附件格式等等。 4.IMAP IMAP使用在接收信息的高級協(xié)議,目前版本為第4版,所以也被稱為IMAP4。需要注意的是在使用IMAP時,郵件服務(wù)器必須支持該協(xié)議。從這個方面講,我們并不能完全使用IMAP來替代POP,不能期待IMAP在任何地方都被支持。假如郵件服務(wù)器支持IMAP,那么我們的郵件程序?qū)⒛軌蚓哂幸韵卤?/span>IMAP所支持的特性:每個用戶在服務(wù)器上可具有多個目錄,這些目錄能在多個用戶之間共享。其與POP相比高級之處顯而易見,但是采取IMAP時,它并不是十分完美的:由于IMAP需要從其它服務(wù)器上接收新信息,將這些信息遞送給用戶,維護(hù)每個用戶的多個目錄,這都為郵件服務(wù)器帶來了高負(fù)載。并且IMAP與POP的一個不同之處是POP用戶在接收郵件時將從郵件服務(wù)器上下載郵件,而IMAP允許用戶直接訪問郵件目錄,所以在郵件服務(wù)器進(jìn)行備份作業(yè)時,由于每個長期使用此郵件系統(tǒng)的用戶所用的郵件目錄會占有很大的空間,這將直接導(dǎo)致郵件服務(wù)器上磁盤空間暴漲。 三、JavaMail介紹 1. JavaMail核心類結(jié)構(gòu) 在javax.mail的包下面存在著一些核心類:Session、Message、Address、Authenticator、Transport、Store、Folder等而且在javax.mail.internet包中還有一些常用的子類。 2.Session Session類定義了基本的郵件會話。就像Http會話那樣,我們進(jìn)行收發(fā)郵件的工作都是基于這個會話的。Session對象利用了java.util.Properties對象獲得了郵件服務(wù)器、用戶名、密碼信息和整個應(yīng)用程序都要使用到的共享信息。 Session類的構(gòu)造方法是私有的,所以我們可以使用Session類提供的getDefaultInstance()這個靜態(tài)工廠方法獲得一個默認(rèn)的Session對象: Properties props = new Properties(); // fill props with any information Session session = Session.getDefaultInstance(props, null); 或者使用getInstance()這個靜態(tài)工廠方法獲得自定義的Session: Properties props = new Properties(); // fill props with any information Session session = Session.getInstance(props, null); 從上面的兩個例子中不難發(fā)現(xiàn),getDefaultInstance()和getInstance()方法的第二個參數(shù)都是null,這是因為在上面的例子中并沒有使用到郵件授權(quán),下文中將對授權(quán)進(jìn)行詳細(xì)介紹。 從很多的實例看,在對mail server進(jìn)行訪問的過程中使用共享的Session是足夠的,即使是工作在多個用戶郵箱的模式下也不例外。 3.Message 當(dāng)我們建立了Session對象后,便可以構(gòu)造要發(fā)送的信息體了。在這里就要用到SUN提供了Message類型。由于Message是一個抽象類,大多數(shù)情況下,我們使用MimeMessage這個具體子類,該類是使用MIME類型、MIME信息頭的郵箱信息。信息頭只能使用US-ASCII字符,而非ASCII字符將通過編碼轉(zhuǎn)換為ASCII的方式使用。為了建立一個MimeMessage對象,我們必須將Session對象作為MimeMessage構(gòu)造方法的參數(shù)傳入: MimeMessage message = new MimeMessage(session); 在建立了MimeMessage對象后,我們需要設(shè)置它的各個part,對于MimeMessage類來說,這些part就是MimePart接口。最基本的設(shè)置信息內(nèi)容的方法就是通過表示信息內(nèi)容和HTML類型的參數(shù)調(diào)用setContent()方法: message.setContent("Hello", "text/html"); 然而,如果我們所使用的MimeMessage中信息內(nèi)容是文本的話,我們便可以直接使用setText()方法來方便的設(shè)置文本內(nèi)容。 message.setText("Hello"); 前面所講的兩種方法,對于文本信息,后者更為合適。而對于其它的一些信息類型,比如HTML信息,則要使用前者。設(shè)置郵件主題可以使用setSubject()方法: message.setSubject("mail subject"); 4.Address 建立了Session和Message之後,接下來要使用郵件地址類:Address。像Message一樣,Address類也是一個抽象類,所以我們將使用javax.mail.internet.InternetAddress這個子類。 通過傳入代表郵件地址的字符串,我們可以建立一個郵件地址類: Address address = new InternetAddress("wang@localhost"); 如果要在郵件地址后面增加名字的話,可以通過傳遞兩個參數(shù):代表郵件地址和名字的字符串來建立一個具有郵件地址和名字的郵件地址類: Address address = new InternetAddress("wang@ localhost ", "wang"); 這里所講的郵件地址類是為了設(shè)置郵件信息的發(fā)信人和收信人而準(zhǔn)備的,在建立了郵件地址類后,我們通過message的setFrom()或者setReplyTo()兩種方法設(shè)置郵件的發(fā)信人: message.setFrom(address); message.setReplyTo(address) 若在郵件中存在多個發(fā)信人地址,我們可用addForm()方法增加發(fā)信人: Address address[] ={new InternetAddress("wang@localhost"), new InternetAddress("fyc@localhost")}; message.addFrom(address); 為了設(shè)置收信人,我們使用addRecipient()方法增加收信人,此方法需要使用Message.RecipientType的常量來區(qū)分收信人的類型: message.addRecipient(type, address) 下面是Message.RecipientType的三個常量: Message.RecipientType.TO 信件接收者 Message.RecipientType.CC 抄送接收者 Message.RecipientType.BCC 暗送接收者 因此,如果我們要發(fā)送郵件給wang,并發(fā)用一個副本給fyc的話,下面的方法將被用到: Address toAddress = new InternetAddress("wang@localhost"); Address ccAddress = new InternetAddress("fyc@localhost"); message.addRecipient(Message.RecipientType.TO, toAddress); message.addRecipient(Message.RecipientType.CC, ccAddress); JavaMail API并沒有提供檢查郵件地址有效性的機(jī)制。當(dāng)然我們可以自己完成這個功能:驗證郵件地址的字符是否按照RFC822規(guī)定的格式書寫或者通過DNS服務(wù)器上的MX記錄驗證等。 5.Authenticator 像java.net類那樣,JavaMail API通過使用授權(quán)者類(Authenticator)以用戶名、密碼的方式訪問那些受到保護(hù)的資源,在這里“資源”就是指郵件服務(wù)器。在javax.mail包中可以找到這個JavaMail的授權(quán)者類(Authenticator)。 在使用Authenticator這個抽象類時,我們必須采用繼承該抽象類的方式,并且該繼承類必須具有返回PasswordAuthentication對象(用于存儲認(rèn)證時要用到的用戶名、密碼)getPasswordAuthentication()方法。并且要在Session中進(jìn)行注冊,使Session能夠了解在認(rèn)證時該使用哪個類。 下面代碼片斷中的MyAuthenticator就是一個Authenticator的子類。 Properties props = new Properties(); // fill props with any information Authenticator auth = new MyAuthenticator(); Session session = Session.getDefaultInstance(props, auth); 6.Transport 在發(fā)送信息時,Transport類將被用到。這個類實現(xiàn)了發(fā)送信息的協(xié)議(通稱為SMTP),此類是一個抽象類,我們可以使用這個類的靜態(tài)方法send()來發(fā)送消息: Transport.send(message); 當(dāng)然,方法是多樣的。我們也可由Session獲得相應(yīng)協(xié)議對應(yīng)的Transport實例。并通過傳遞用戶名、密碼、郵件服務(wù)器主機(jī)名等參數(shù)建立與郵件服務(wù)器的連接,并使用sendMessage()方法將信息發(fā)送,最后關(guān)閉連接: message.saveChanges(); // implicit with send() Transport transport = session.getTransport("smtp"); transport.connect(host, username, password); transport.sendMessage(message, message.getAllRecipients()); transport.close(); 上面的方法是一個很好的方法,尤其是在我們在同一個郵件服務(wù)器上發(fā)送多個郵件時。因為這時我們將在連接郵件服務(wù)器后連續(xù)發(fā)送郵件,然后再關(guān)閉掉連接。send()這個基本的方法是在每次調(diào)用時進(jìn)行與郵件服務(wù)器的連接的,對于在同一個郵件服務(wù)器上發(fā)送多個郵件來講可謂低效的方式。 注意:如果需要在發(fā)送郵件過程中監(jiān)控mail命令的話,可以在發(fā)送前設(shè)置debug標(biāo)志: session.setDebug(true) 7.Store和Folder 接收郵件和發(fā)送郵件很類似都要用到Session。但是在獲得Session后,我們需要從Session中獲取特定類型的Store,然后連接到Store,這里的Store代表了存儲郵件的郵件服務(wù)器。在連接Store的過程中,極有可能需要用到用戶名、密碼或者Authenticator。 // Store store = session.getStore("imap"); Store store = session.getStore("pop3"); store.connect(host, username, password); 在連接到Store后,一個Folder對象即目錄對象將通過Store的getFolder()方法被返回,我們可從這個Folder中讀取郵件信息: Folder folder = store.getFolder("INBOX"); folder.open(Folder.READ_ONLY); Message message[] = folder.getMessages(); 上面的例子首先從Store中獲得INBOX這個Folder(對于POP3協(xié)議只有一個名為INBOX的Folder有效),然后以只讀(Folder.READ_ONLY)的方式打開Folder,最后調(diào)用Folder的getMessages()方法得到目錄中所有Message的數(shù)組。 注意:對于POP3協(xié)議只有一個名為INBOX的Folder有效,而對于IMAP協(xié)議,我們可以訪問多個Folder,而且Folder的getMessages()方法時采取了很智能的方式:首先接收新郵件列表,然后再需要的時候(比如讀取郵件內(nèi)容)才從郵件服務(wù)器讀取郵件內(nèi)容。 在讀取郵件時,我們可以用Message類的getContent()方法接收郵件或是writeTo()方法將郵件保存,getContent()方法只接收郵件內(nèi)容(不包含郵件頭),而writeTo()方法將包括郵件頭。 System.out.println(((MimeMessage)message).getContent()); 在讀取郵件內(nèi)容后,別忘記了關(guān)閉Folder和Store。 folder.close(aBoolean); store.close(); 傳遞給Folder.close()方法的boolean 類型參數(shù)表示是否在刪除操作郵件后更新Folder。 8. MimeMultpart 一般保存電子郵件內(nèi)容的容器是Multipart抽象類,它定義了增加和刪除及獲得電子郵件不同部分內(nèi)容的方法.由于Multipart是抽象類,我們必須為它使用一個具體的子類,JavaMail API提供javax.mail.Internet.MimeMultpart類來使用MimeMessage對象: MimeMultipart multipart = new MimeMultipart(); 注:我們使用MimeMultipart對象的一個方法是addBodyPart(),它在我們的電子郵件內(nèi)容里添加BodyPart(BodyPart類在下面緊接著要介紹)對象.消息可以有很多部分,一個BodyPart可以代表一個部分 9.MimeBodyPart MimeBodyPart是BodyPart具體用于mimeMessage的一個子類. 1.一個MIME類型 2.匹配這個類型的內(nèi)容 用法:MimeBodyPart mdp = new MimeBodyPart(); String text = "Hello JavaMail!"; mdp.setContent(text, "text/plain"); //定義MIME類型為text/plain,并設(shè)置MimeBodyPart的內(nèi)容。 10. javax.activation.DataHandler JavaMail API不限制信息只為文本,任何形式的信息都可能是MimeMessage的一部分.除了文本信息,文件附件包含在電子郵件信息的一部分是很普遍的,.JavaMail API通過使用DataHandler對象,提供一個允許我們包含非文本BodyPart對象的簡便方法. 用法:DataHandler dh = new DataHandler(text, type); mdp.setDatahandler(dh); //mdp是一個MimeBodyPart對象 11. javax.activation.FileDataSource FileDataSource對象可以表示本地文件和服務(wù)器可以直接訪問的資源.一個本地文件可以通過創(chuàng)建一個新的MimeBodyPart對象附在一個mimeMessage對象上. 用法::MimeMultipart mm = new MimeMultipart(); MimeBodyPart mdp = new MimeBodyPart(); FileDataSource fds = new FileDataSource("c:/exam.txt"); mdp.setDataHandler(new DataHandler(fds)); //設(shè)置數(shù)據(jù)源 mm.addBodyPart(mdp); //為當(dāng)前消息MimeMultipart對象增加MimeBodyPart 12 .javax.activation.URLDataSource 遠(yuǎn)程資源,URL不會指向它們,由一個URLDataSource對象表示.一個遠(yuǎn)程資源可以通過創(chuàng)建一個新mimeBodyPart對象附在一個mimeMessage對象上(同FileDataSource差不多). 用法::FileDataSource唯一不同的是數(shù)據(jù)源的設(shè)置: 四、用javaMail實現(xiàn)郵件發(fā)送、讀取步驟 環(huán)境介紹:本例所用的環(huán)境:jdk1.5,eclipse3.1;需導(dǎo)入的包:mail.jar, activation.jar 由於是應(yīng)用程序只需新建一個java工程,工程目錄結(jié)構(gòu):
![]() 右鍵點擊java工程名javaMailTest選擇內(nèi)容/Properties──點擊java建置路徑──點擊新增外部JAR如圖
![]() 選擇mail和activeation兩個包。 1.啟動郵件服務(wù)器:運行http://jakrata.網(wǎng)站下載的james服務(wù)器下的james/bin里的run.bat就可以啟動了服務(wù)器如圖:
![]() 在DOS用telnet localhost 4555 登錄郵件服務(wù)器如圖: ![]() Login id: root 輸入root後會提示輸入密碼
![]() 同樣輸入root可登錄郵件服務(wù)器,用adduser 用戶名 密碼 命令可添加用戶 2.郵件系統(tǒng)工作過程
![]() 3.發(fā)郵件 3.1.用import導(dǎo)入所需要的包:java.util.*; javax.mail.*; avax.mail.internet.*; javax.activation.*; 3.2.創(chuàng)建java.util.Properties對象並將郵件服務(wù)器、郵件傳輸協(xié)議放入其中,如果需要授權(quán)訪問還要存放訪問用戶名、密碼信息。 Properties props = System.getProperties(); props.put("mail.transpost.protocol", "smtp"); props.put("mail.smtp.host", host); 3.3.通過以上的Properties對象實例化一個會話Session。 Session session = Session.getDefaultInstance(props, null); 3.4.用MimeMessage類通過創(chuàng)建的Session構(gòu)建一個消息,並設(shè)置消息提各個元素如:發(fā)信人、收信人、主題、內(nèi)容、附件等 MimeMessage msg = new MimeMessage(session); msg.setFrom(new InternetAddress(from)); InternetAddress[] address = { new InternetAddress(to) }; msg.setRecipients(Message.RecipientType.TO, address); msg.setSubject(subject); 3.5.用Transport類的send方法發(fā)送構(gòu)建的消息:Transport.send(msg); 3.6.以java應(yīng)用程序方式運行應(yīng)用程序mail.java發(fā)送郵件正常會彈出如下圖框
4.讀郵件 4.1.用import導(dǎo)入所需要的包:java.io.*; java.text.*; avax.mail.internet.*; javax.mail.*; java.util.* 4.2.創(chuàng)建java.util.Properties對象:Properties props = new Properties(); 4.3.通過以上的Properties對象實例化一個會話Session: Session session = Session.getDefaultInstance(props, null); 4.4.通過Session創(chuàng)建郵件服務(wù)器Store,並指定讀取郵件協(xié)議:Store store = session.getStore("pop3");: 4.5.連接郵件服務(wù)器並傳入服務(wù)器名、用戶、密碼信息:store.connect(hostname, username, password); 4.6.取得郵件服務(wù)器目錄,對於用POP3協(xié)議讀取只有“INBOX”目錄: Folder folder = store.getFolder("INBOX"); 4.7.打開目錄,並指定郵件讀取方式為只讀、讀寫或其它:folder.open(Folder.READ_ONLY); 4.8.讀取這個用戶下的所有郵件放在消息數(shù)組裡:Message message[] = folder.getMessages(); 4.9.讀取在消息數(shù)組中的每個郵件,在讀取郵件需要按照郵件的各個部分分別讀取,如讀取發(fā)信人、讀取收信人、讀取主題、讀取郵件內(nèi)容、讀取郵件附件等,並且還要根郵件的各個部分在發(fā)送時的MIME類型編碼進(jìn)行相應(yīng)的解碼。 4.10.以java應(yīng)用程序方式運行應(yīng)用程序readMail.java如正常會交替彈出如下兩個圖框 並且在控制臺會輸出所有郵件信息: ![]() 附源碼:發(fā)送郵件源碼,讀取郵件源碼
1.授權(quán)訪問 import javax.mail.*; public class Email_Autherticatorbean extends Authenticator { private String m_username = null; //用戶名 private String m_userpass = null; //密碼 public void setUsername(String username) { m_username = username; } public void setUserpass(String userpass) { m_userpass = userpass; } public Email_Autherticatorbean(String username, String userpass) { super(); setUsername(username); setUserpass(userpass); } public PasswordAuthentication getPasswordAuthentication() { return new PasswordAuthentication(m_username, m_userpass); //存儲驗證的用戶名、密碼 } }
2.發(fā)送郵件 import java.util.*; import javax.mail.*; import javax.mail.internet.*; import javax.activation.*; public class mail { // 定義發(fā)件人、收件人、主題等 String to = ""; String from = ""; String host = ""; String filename = ""; String subject = ""; Vector file = new Vector(); // 保存發(fā)送附件的文件名的集合 /** * 構(gòu)造函數(shù) */ public mail(String to, String from, String smtpServer, String subject) { // 初始化發(fā)件人、收件人、smtp服務(wù)器、主題 this.to = to; this.from = from; this.host = smtpServer; this.subject = subject; } /** * 收集附件名 */ public void attachfile(String fname) { file.addElement(fname); } /** * 開始發(fā)送信件 */ public boolean startSend() { Properties props = System.getProperties(); // 創(chuàng)建Properties對象 props.put("mail.transpost.protocol", "smtp"); //郵件傳輸協(xié)議 props.put("mail.smtp.host", host); // 創(chuàng)建信件服務(wù)器 發(fā)內(nèi)部郵件:Session session = Session.getDefaultInstance(props, null); // 得到默認(rèn)的會話對象 //props.put("mail.smtp.auth", "true"); 用於發(fā) //props.put("mail.smpt.port", "25"); 外部郵 //Email_Autherticatorbean auth = new Email_Autherticatorbean("ypfeng2005", "20052005"); // 驗證 件 // session //Session session = Session.getInstance(props, auth); // 得到通過驗證會話 session.setDebug(true); // 輸出MAIL命令 try { MimeMessage msg = new MimeMessage(session); // 創(chuàng)建消息,并初始化該消息 msg.setFrom(new InternetAddress(from)); InternetAddress[] address = { new InternetAddress(to) }; msg.setRecipients(Message.RecipientType.TO, address); msg.setSubject(subject); msg.setContent("this is my mail", "text/html;charset=big5"); //msg.setText("mail?。?!"); Multipart mp = new MimeMultipart();// 后面的BodyPart將加入到此處創(chuàng)建的Multipart中 Enumeration efile = file.elements();// 利用枚舉器遍歷集合 // 檢查序列中是否還有更多的對象 while (efile.hasMoreElements()) { MimeBodyPart mbp = new MimeBodyPart(); // 選擇出每一個附件名 filename = efile.nextElement().toString(); // 得到數(shù)據(jù)源 FileDataSource fds = new FileDataSource(filename); // 得到附件本身并至入BodyPart mbp.setDataHandler(new DataHandler(fds)); // 得到文件名同樣至入BodyPart mbp.setFileName(fds.getName()); mp.addBodyPart(mbp); } // 移走集合中的所有元素 file.removeAllElements(); // Multipart加入到信件 msg.setContent(mp); // 設(shè)置信件頭的發(fā)送日期 msg.setSentDate(new Date()); // 發(fā)送信件 Transport.send(msg); System.out.println("mail send successful!!"); } catch (MessagingException mex) { mex.printStackTrace(); Exception ex = null; if ((ex = mex.getNextException()) != null) { ex.printStackTrace(); } return false; } return true; } public static void main(String[] args) { mail sendmail=new mail("fyc@localhost","wang@localhost","localhost","test");//發(fā)內(nèi)部郵件 //mail sendmail=new mail("fff@163.com", "ppp@163.com","smtp.163.com", "test");//發(fā)外部郵件 sendmail.attachfile("D:/spring_reference.pdf");//添加附件 sendmail.startSend();//發(fā)送郵件 } }
3.讀取郵件 import java.io.*; import java.text.*; import java.util.*; import javax.mail.*; import javax.mail.internet.*; public class readMail { private MimeMessage mimeMessage = null; private String saveAttachPath = ""; // 附件下載后的存放目錄 private StringBuffer bodytext = new StringBuffer();// 存放郵件內(nèi)容的StringBuffer對象 private String dateformat = "yy-MM-dd HH:mm"; // 默認(rèn)的日前顯示格式 /** * * 構(gòu)造函數(shù),初始化一個MimeMessage對象 */ public readMail() { } public readMail(MimeMessage mimeMessage) { this.mimeMessage = mimeMessage; System.out.println("create a PraseMimeMessage object........"); } /** * * 獲取一個MimeMessage對象 */ public void setMimeMessage(MimeMessage mimeMessage) { this.mimeMessage = mimeMessage; } /** * * 獲得發(fā)件人的地址和姓名 */ public String getFrom() throws Exception { InternetAddress address[] = (InternetAddress[]) mimeMessage.getFrom(); String from = address[0].getAddress(); if (from == null) from = ""; String personal = address[0].getPersonal(); if (personal == null) personal = ""; String fromaddr = personal + "<" + from + ">"; return fromaddr; } /** * 獲得郵件的收件人,抄送,和密送的地址和姓名,根據(jù)所傳遞的參數(shù)的不同如 * to 獲得郵件的收件人 cc 獲得郵件的抄送人地址 bcc 獲得郵件的密送人地址 */ public String getMailAddress(String type) throws Exception { String mailaddr = ""; String addtype = type.toUpperCase(); InternetAddress[] address = null; if (addtype.equals("TO") || addtype.equals("CC") || addtype.equals("BCC")) { if (addtype.equals("TO")) { address = (InternetAddress[]) mimeMessage .getRecipients(Message.RecipientType.TO); } else if (addtype.equals("CC")) { address = (InternetAddress[]) mimeMessage .getRecipients(Message.RecipientType.CC); } else { address = (InternetAddress[]) mimeMessage .getRecipients(Message.RecipientType.BCC); } if (address != null) { for (int i = 0; i < address.length; i++) { String email = address[i].getAddress(); if (email == null) email = ""; else { email = MimeUtility.decodeText(email); } String personal = address[i].getPersonal(); if (personal == null) personal = ""; else { personal = MimeUtility.decodeText(personal); } String compositeto = personal + "<" + email + ">"; mailaddr += "," + compositeto; } mailaddr = mailaddr.substring(1); } } else { throw new Exception("Error emailaddr type!"); } return mailaddr; } /** * * 獲得郵件主題 */ public String getSubject() throws MessagingException { String subject = ""; try { subject = MimeUtility.decodeText(mimeMessage.getSubject()); if (subject == null) subject = ""; } catch (Exception exce) { } return subject; } /** * * 獲得郵件的發(fā)送日期 */ public String getSentDate() throws Exception { Date sentdate = mimeMessage.getSentDate(); SimpleDateFormat format = new SimpleDateFormat(dateformat); return format.format(sentdate); } /** * * 獲得郵件的正文內(nèi)容 */ public String getBodyText() { return bodytext.toString(); } /** * 解析郵件,把得到的郵件內(nèi)容保存到一個StringBuffer對象中,解析郵件 * * 主要是根據(jù)MimeType類型的不同執(zhí)行不同的操作,一步一步的解析 */ public void getMailContent(Part part) throws Exception { String contenttype = part.getContentType(); int nameindex = contenttype.indexOf("name"); boolean conname = false; if (nameindex != -1) conname = true; System.out.println("CONTENTTYPE: " + contenttype); if (part.isMimeType("text/plain") && !conname) { bodytext.append((String) part.getContent()); } else if (part.isMimeType("text/html") && !conname) { bodytext.append((String) part.getContent()); } else if (part.isMimeType("multipart/*")) { Multipart multipart = (Multipart) part.getContent(); int counts = multipart.getCount(); for (int i = 0; i < counts; i++) { getMailContent(multipart.getBodyPart(i)); } } else if (part.isMimeType("message/rfc822")) { getMailContent((Part) part.getContent()); } else { } } /** * * 判斷此郵件是否需要回執(zhí),如果需要回執(zhí)返回"true",否則返回"false" */ public boolean getReplySign() throws MessagingException { boolean replysign = false; String needreply[] = mimeMessage .getHeader("Disposition-Notification-To"); if (needreply != null) { replysign = true; } return replysign; } /** * *獲得此郵件的Message-ID */ public String getMessageId() throws MessagingException { return mimeMessage.getMessageID(); } /** * 判斷此郵件是否已讀,如果未讀返回false,反之返回true */ public boolean isNew() throws MessagingException { boolean isnew = false; Flags flags = ((Message) mimeMessage).getFlags(); Flags.Flag[] flag = flags.getSystemFlags(); System.out.println("flags‘s length: " + flag.length); for (int i = 0; i < flag.length; i++) { if (flag[i] == Flags.Flag.SEEN) { isnew = true; System.out.println("seen Message......."); break; } } return isnew; } /** * * 判斷此郵件是否包含附件 */ public boolean isContainAttach(Part part) throws Exception { boolean attachflag = false; //String contentType = part.getContentType(); if (part.isMimeType("multipart/*")) { Multipart mp = (Multipart) part.getContent(); for (int i = 0; i < mp.getCount(); i++) { BodyPart mpart = mp.getBodyPart(i); String disposition = mpart.getDisposition(); if ((disposition != null) && ((disposition.equals(Part.ATTACHMENT)) || (disposition .equals(Part.INLINE)))) attachflag = true; else if (mpart.isMimeType("multipart/*")) { attachflag = isContainAttach((Part) mpart); } else { String contype = mpart.getContentType(); if (contype.toLowerCase().indexOf("application") != -1) attachflag = true; if (contype.toLowerCase().indexOf("name") != -1) attachflag = true; } } } else if (part.isMimeType("message/rfc822")) { attachflag = isContainAttach((Part) part.getContent()); } return attachflag; } /** * 保存附件 */ public void saveAttachMent(Part part) throws Exception { String fileName = ""; if (part.isMimeType("multipart/*")) { Multipart mp = (Multipart) part.getContent(); for (int i = 0; i < mp.getCount(); i++) { BodyPart mpart = mp.getBodyPart(i); String disposition = mpart.getDisposition(); if ((disposition != null) && ((disposition.equals(Part.ATTACHMENT)) || (disposition .equals(Part.INLINE)))) { fileName = mpart.getFileName(); if (fileName.toLowerCase().indexOf("gb2312") != -1) { fileName = MimeUtility.decodeText(fileName); } saveFile(fileName, mpart.getInputStream()); } else if (mpart.isMimeType("multipart/*")) { saveAttachMent(mpart); } else { fileName = mpart.getFileName(); if ((fileName != null) && (fileName.toLowerCase().indexOf("GB2312") != -1)) { fileName = MimeUtility.decodeText(fileName); saveFile(fileName, mpart.getInputStream()); } } } } else if (part.isMimeType("message/rfc822")) { saveAttachMent((Part) part.getContent()); } } /** * 設(shè)置附件存放路徑 */ public void setAttachPath(String attachpath) { this.saveAttachPath = attachpath; } /** * 設(shè)置日期顯示格式 */ public void setDateFormat(String format) throws Exception { this.dateformat = format; } /** * 獲得附件存放路徑 */ public String getAttachPath() { return saveAttachPath; } /** * * 保存附件到指定目錄里 */ private void saveFile(String fileName, InputStream in) throws Exception { String osName = System.getProperty("os.name"); String storedir = getAttachPath(); String separator = ""; if (osName == null) osName = ""; if (osName.toLowerCase().indexOf("win") != -1) { separator = "\\"; if (storedir == null || storedir.equals("")) storedir = "c:\\tmp"; } else { separator = "/"; storedir = "/tmp"; } File storefile = new File(storedir + separator + fileName); System.out.println("storefile‘s path: " + storefile.toString()); // for(int i=0;storefile.exists();i++){ // storefile = new File(storedir+separator+fileName+i); // } BufferedOutputStream bos = null; BufferedInputStream bis = null; try { bos = new BufferedOutputStream(new FileOutputStream(storefile)); bis = new BufferedInputStream(in); int c; while ((c = bis.read()) != -1) { bos.write(c); bos.flush(); } } catch (Exception exception) { exception.printStackTrace(); throw new Exception("文件保存失敗!"); } finally { bos.close(); bis.close(); } } /** * * 類測試 */ public static void main(String args[]) throws Exception { String host = "localhost"; // 主機(jī)名/ip String username = "fyc"; // 用戶名 String password = "fyc"; // 密碼 Properties props = new Properties(); Session session = Session.getDefaultInstance(props, null); Store store = session.getStore("pop3");// 郵件服務(wù)器 store.connect(host, username, password); Folder folder = store.getFolder("INBOX"); // 郵件服務(wù)器目錄 folder.open(Folder.READ_ONLY); Message message[] = folder.getMessages(); // 獲得郵件 System.out.println("Messages‘s length: " + message.length); readMail pmm = null; for (int i = 0; i < message.length; i++) { pmm = new readMail((MimeMessage) message[i]); System.out.println("Message " + i + " subject: " + pmm.getSubject()); System.out.println("Message " + i + " sentdate: " + pmm.getSentDate()); System.out.println("Message " + i + " replysign: " + pmm.getReplySign()); System.out.println("Message " + i + " hasRead: " + pmm.isNew()); System.out.println("Message " + i + " containAttachment: " + mm.isContainAttach((Part) message[i])); System.out.println("Message " + i + " from: " + pmm.getFrom()); System.out.println("Message " + i + " to: " + pmm.getMailAddress("to")); System.out.println("Message " + i + " cc: " + pmm.getMailAddress("cc")); System.out.println("Message " + i + " bcc: " + pmm.getMailAddress("bcc")); pmm.setDateFormat("yy年MM月dd日 HH:mm"); System.out.println("Message " + i + " sentdate: " + pmm.getSentDate()); System.out.println("Message " + i + " Message-ID: " + pmm.getMessageId()); pmm.getMailContent((Part) message[i]); System.out.println("Message " + i + " bodycontent: \r\n" + pmm.getBodyText()); pmm.setAttachPath("d:\\tmp"); pmm.saveAttachMent((Part) message[i]); } } } |
|