javaMail應(yīng)用
JavaMail API是讀取、撰寫(xiě)、發(fā)送電子信息的可選包。 一、環(huán)境配置: 為了運(yùn)行Javamail。我們需要在classpath里導(dǎo)入兩個(gè)包:mail.jar和activation.jar, mail.jar實(shí)現(xiàn)提供了對(duì)SMTP、IMAP4、POP3的支持,activation.jar增加了對(duì)任何數(shù)據(jù)塊的分類(lèi)、以及對(duì)它們的處理的特性。這些特性是JavaMail API需要的 為了要發(fā)送郵件和接收郵件,我們必須要遵守smtp和pop3協(xié)議,不過(guò)還有其它協(xié)議也可執(zhí)行(如IMAP)。如果把本機(jī)當(dāng)作服務(wù)器來(lái)發(fā)送郵件可在http://jakrata.網(wǎng)站里下載james郵件服務(wù)器,然后解壓在本機(jī)上。運(yùn)行james/bin里的run.bat就可以啟動(dòng)了服務(wù)器。 在DOS里登錄郵件服務(wù)器命令為:telnet localhost 4555 增加郵箱用戶(hù)名命令為:adduser 用戶(hù)名 密碼 如:adduser fyc fyc 就建立了這樣一個(gè)郵箱fyc@localhost 密碼為:fyc 如果想要更多功能用help命令。 注意:如果在本機(jī)裝了郵件服務(wù)器的話,只能在本機(jī)局域網(wǎng)里申請(qǐng)郵箱,發(fā)送和接收。不能發(fā)送到外部的郵箱里去。如果用外部的郵件服務(wù)器像比如163的服務(wù)器等就可以隨心所欲的發(fā)郵件了。 二、相關(guān)協(xié)議介紹: 常用到的協(xié)議為SMTP、POP、MIME、IMAP,雖然JavaMail API是被設(shè)計(jì)為與協(xié)議無(wú)關(guān)的,但如果我們使用的功能并不被我們選擇的協(xié)議支持,那么JavaMail API就不可能發(fā)揮它提功能。 1.SMTP 簡(jiǎn)單郵件傳輸協(xié)議定義了遞送郵件的機(jī)制。我們將使用基于Java-Mail的程序與公司或者ISP的SMTP服務(wù)器進(jìn)行通訊。這個(gè)SMTP服務(wù)器將郵件轉(zhuǎn)發(fā)到接收者的SMTP服務(wù)器,直至最后被接收者通過(guò)POP或者IMAP協(xié)議獲取。 2.POP POP是一種郵局協(xié)議,目前為第3個(gè)版本,即POP3。POP定義了一種用戶(hù)如何獲得郵件的機(jī)制。它規(guī)定了每個(gè)用戶(hù)使用一個(gè)單獨(dú)的郵箱。 3.MIME MIME并不是用于傳送郵件的協(xié)議,它作為多用途郵件的擴(kuò)展定義了郵件內(nèi)容的格式:信息格式、附件格式等等。 4.IMAP IMAP使用在接收信息的高級(jí)協(xié)議,目前版本為第4版,所以也被稱(chēng)為IMAP4。需要注意的是在使用IMAP時(shí),郵件服務(wù)器必須支持該協(xié)議。從這個(gè)方面講,我們并不能完全使用IMAP來(lái)替代POP,不能期待IMAP在任何地方都被支持。假如郵件服務(wù)器支持IMAP,那么我們的郵件程序?qū)⒛軌蚓哂幸韵卤?/span>IMAP所支持的特性:每個(gè)用戶(hù)在服務(wù)器上可具有多個(gè)目錄,這些目錄能在多個(gè)用戶(hù)之間共享。其與POP相比高級(jí)之處顯而易見(jiàn),但是采取IMAP時(shí),它并不是十分完美的:由于IMAP需要從其它服務(wù)器上接收新信息,將這些信息遞送給用戶(hù),維護(hù)每個(gè)用戶(hù)的多個(gè)目錄,這都為郵件服務(wù)器帶來(lái)了高負(fù)載。并且IMAP與POP的一個(gè)不同之處是POP用戶(hù)在接收郵件時(shí)將從郵件服務(wù)器上下載郵件,而IMAP允許用戶(hù)直接訪問(wèn)郵件目錄,所以在郵件服務(wù)器進(jìn)行備份作業(yè)時(shí),由于每個(gè)長(zhǎng)期使用此郵件系統(tǒng)的用戶(hù)所用的郵件目錄會(huì)占有很大的空間,這將直接導(dǎo)致郵件服務(wù)器上磁盤(pán)空間暴漲。 三、JavaMail介紹 1. JavaMail核心類(lèi)結(jié)構(gòu) 在javax.mail的包下面存在著一些核心類(lèi):Session、Message、Address、Authenticator、Transport、Store、Folder等而且在javax.mail.internet包中還有一些常用的子類(lèi)。 2.Session Session類(lèi)定義了基本的郵件會(huì)話。就像Http會(huì)話那樣,我們進(jìn)行收發(fā)郵件的工作都是基于這個(gè)會(huì)話的。Session對(duì)象利用了java.util.Properties對(duì)象獲得了郵件服務(wù)器、用戶(hù)名、密碼信息和整個(gè)應(yīng)用程序都要使用到的共享信息。 Session類(lèi)的構(gòu)造方法是私有的,所以我們可以使用Session類(lèi)提供的getDefaultInstance()這個(gè)靜態(tài)工廠方法獲得一個(gè)默認(rèn)的Session對(duì)象: Properties props = new Properties(); // fill props with any information Session session = Session.getDefaultInstance(props, null); 或者使用getInstance()這個(gè)靜態(tài)工廠方法獲得自定義的Session: Properties props = new Properties(); // fill props with any information Session session = Session.getInstance(props, null); 從上面的兩個(gè)例子中不難發(fā)現(xiàn),getDefaultInstance()和getInstance()方法的第二個(gè)參數(shù)都是null,這是因?yàn)樵谏厦娴睦又胁](méi)有使用到郵件授權(quán),下文中將對(duì)授權(quán)進(jìn)行詳細(xì)介紹。 從很多的實(shí)例看,在對(duì)mail server進(jìn)行訪問(wèn)的過(guò)程中使用共享的Session是足夠的,即使是工作在多個(gè)用戶(hù)郵箱的模式下也不例外。 3.Message 當(dāng)我們建立了Session對(duì)象后,便可以構(gòu)造要發(fā)送的信息體了。在這里就要用到SUN提供了Message類(lèi)型。由于Message是一個(gè)抽象類(lèi),大多數(shù)情況下,我們使用MimeMessage這個(gè)具體子類(lèi),該類(lèi)是使用MIME類(lèi)型、MIME信息頭的郵箱信息。信息頭只能使用US-ASCII字符,而非ASCII字符將通過(guò)編碼轉(zhuǎn)換為ASCII的方式使用。為了建立一個(gè)MimeMessage對(duì)象,我們必須將Session對(duì)象作為MimeMessage構(gòu)造方法的參數(shù)傳入: MimeMessage message = new MimeMessage(session); 在建立了MimeMessage對(duì)象后,我們需要設(shè)置它的各個(gè)part,對(duì)于MimeMessage類(lèi)來(lái)說(shuō),這些part就是MimePart接口。最基本的設(shè)置信息內(nèi)容的方法就是通過(guò)表示信息內(nèi)容和HTML類(lèi)型的參數(shù)調(diào)用setContent()方法: message.setContent("Hello", "text/html"); 然而,如果我們所使用的MimeMessage中信息內(nèi)容是文本的話,我們便可以直接使用setText()方法來(lái)方便的設(shè)置文本內(nèi)容。 message.setText("Hello"); 前面所講的兩種方法,對(duì)于文本信息,后者更為合適。而對(duì)于其它的一些信息類(lèi)型,比如HTML信息,則要使用前者。設(shè)置郵件主題可以使用setSubject()方法: message.setSubject("mail subject"); 4.Address 建立了Session和Message之後,接下來(lái)要使用郵件地址類(lèi):Address。像Message一樣,Address類(lèi)也是一個(gè)抽象類(lèi),所以我們將使用javax.mail.internet.InternetAddress這個(gè)子類(lèi)。 通過(guò)傳入代表郵件地址的字符串,我們可以建立一個(gè)郵件地址類(lèi): Address address = new InternetAddress("wang@localhost"); 如果要在郵件地址后面增加名字的話,可以通過(guò)傳遞兩個(gè)參數(shù):代表郵件地址和名字的字符串來(lái)建立一個(gè)具有郵件地址和名字的郵件地址類(lèi): Address address = new InternetAddress("wang@ localhost ", "wang"); 這里所講的郵件地址類(lèi)是為了設(shè)置郵件信息的發(fā)信人和收信人而準(zhǔn)備的,在建立了郵件地址類(lèi)后,我們通過(guò)message的setFrom()或者setReplyTo()兩種方法設(shè)置郵件的發(fā)信人: message.setFrom(address); message.setReplyTo(address) 若在郵件中存在多個(gè)發(fā)信人地址,我們可用addForm()方法增加發(fā)信人: Address address[] ={new InternetAddress("wang@localhost"), new InternetAddress("fyc@localhost")}; message.addFrom(address); 為了設(shè)置收信人,我們使用addRecipient()方法增加收信人,此方法需要使用Message.RecipientType的常量來(lái)區(qū)分收信人的類(lèi)型: message.addRecipient(type, address) 下面是Message.RecipientType的三個(gè)常量: Message.RecipientType.TO 信件接收者 Message.RecipientType.CC 抄送接收者 Message.RecipientType.BCC 暗送接收者 因此,如果我們要發(fā)送郵件給wang,并發(fā)用一個(gè)副本給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并沒(méi)有提供檢查郵件地址有效性的機(jī)制。當(dāng)然我們可以自己完成這個(gè)功能:驗(yàn)證郵件地址的字符是否按照RFC822規(guī)定的格式書(shū)寫(xiě)或者通過(guò)DNS服務(wù)器上的MX記錄驗(yàn)證等。 5.Authenticator 像java.net類(lèi)那樣,JavaMail API通過(guò)使用授權(quán)者類(lèi)(Authenticator)以用戶(hù)名、密碼的方式訪問(wèn)那些受到保護(hù)的資源,在這里“資源”就是指郵件服務(wù)器。在javax.mail包中可以找到這個(gè)JavaMail的授權(quán)者類(lèi)(Authenticator)。 在使用Authenticator這個(gè)抽象類(lèi)時(shí),我們必須采用繼承該抽象類(lèi)的方式,并且該繼承類(lèi)必須具有返回PasswordAuthentication對(duì)象(用于存儲(chǔ)認(rèn)證時(shí)要用到的用戶(hù)名、密碼)getPasswordAuthentication()方法。并且要在Session中進(jìn)行注冊(cè),使Session能夠了解在認(rèn)證時(shí)該使用哪個(gè)類(lèi)。 下面代碼片斷中的MyAuthenticator就是一個(gè)Authenticator的子類(lèi)。 Properties props = new Properties(); // fill props with any information Authenticator auth = new MyAuthenticator(); Session session = Session.getDefaultInstance(props, auth); 6.Transport 在發(fā)送信息時(shí),Transport類(lèi)將被用到。這個(gè)類(lèi)實(shí)現(xiàn)了發(fā)送信息的協(xié)議(通稱(chēng)為SMTP),此類(lèi)是一個(gè)抽象類(lèi),我們可以使用這個(gè)類(lèi)的靜態(tài)方法send()來(lái)發(fā)送消息: Transport.send(message); 當(dāng)然,方法是多樣的。我們也可由Session獲得相應(yīng)協(xié)議對(duì)應(yīng)的Transport實(shí)例。并通過(guò)傳遞用戶(hù)名、密碼、郵件服務(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(); 上面的方法是一個(gè)很好的方法,尤其是在我們?cè)谕粋€(gè)郵件服務(wù)器上發(fā)送多個(gè)郵件時(shí)。因?yàn)檫@時(shí)我們將在連接郵件服務(wù)器后連續(xù)發(fā)送郵件,然后再關(guān)閉掉連接。send()這個(gè)基本的方法是在每次調(diào)用時(shí)進(jìn)行與郵件服務(wù)器的連接的,對(duì)于在同一個(gè)郵件服務(wù)器上發(fā)送多個(gè)郵件來(lái)講可謂低效的方式。 注意:如果需要在發(fā)送郵件過(guò)程中監(jiān)控mail命令的話,可以在發(fā)送前設(shè)置debug標(biāo)志: session.setDebug(true) 7.Store和Folder 接收郵件和發(fā)送郵件很類(lèi)似都要用到Session。但是在獲得Session后,我們需要從Session中獲取特定類(lèi)型的Store,然后連接到Store,這里的Store代表了存儲(chǔ)郵件的郵件服務(wù)器。在連接Store的過(guò)程中,極有可能需要用到用戶(hù)名、密碼或者Authenticator。 // Store store = session.getStore("imap"); Store store = session.getStore("pop3"); store.connect(host, username, password); 在連接到Store后,一個(gè)Folder對(duì)象即目錄對(duì)象將通過(guò)Store的getFolder()方法被返回,我們可從這個(gè)Folder中讀取郵件信息: Folder folder = store.getFolder("INBOX"); folder.open(Folder.READ_ONLY); Message message[] = folder.getMessages(); 上面的例子首先從Store中獲得INBOX這個(gè)Folder(對(duì)于POP3協(xié)議只有一個(gè)名為INBOX的Folder有效),然后以只讀(Folder.READ_ONLY)的方式打開(kāi)Folder,最后調(diào)用Folder的getMessages()方法得到目錄中所有Message的數(shù)組。 注意:對(duì)于POP3協(xié)議只有一個(gè)名為INBOX的Folder有效,而對(duì)于IMAP協(xié)議,我們可以訪問(wèn)多個(gè)Folder,而且Folder的getMessages()方法時(shí)采取了很智能的方式:首先接收新郵件列表,然后再需要的時(shí)候(比如讀取郵件內(nèi)容)才從郵件服務(wù)器讀取郵件內(nèi)容。 在讀取郵件時(shí),我們可以用Message類(lèi)的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 類(lèi)型參數(shù)表示是否在刪除操作郵件后更新Folder。 8. MimeMultpart 一般保存電子郵件內(nèi)容的容器是Multipart抽象類(lèi),它定義了增加和刪除及獲得電子郵件不同部分內(nèi)容的方法.由于Multipart是抽象類(lèi),我們必須為它使用一個(gè)具體的子類(lèi),JavaMail API提供javax.mail.Internet.MimeMultpart類(lèi)來(lái)使用MimeMessage對(duì)象: MimeMultipart multipart = new MimeMultipart(); 注:我們使用MimeMultipart對(duì)象的一個(gè)方法是addBodyPart(),它在我們的電子郵件內(nèi)容里添加BodyPart(BodyPart類(lèi)在下面緊接著要介紹)對(duì)象.消息可以有很多部分,一個(gè)BodyPart可以代表一個(gè)部分 9.MimeBodyPart MimeBodyPart是BodyPart具體用于mimeMessage的一個(gè)子類(lèi). 1.一個(gè)MIME類(lèi)型 2.匹配這個(gè)類(lèi)型的內(nèi)容 用法:MimeBodyPart mdp = new MimeBodyPart(); String text = "Hello JavaMail!"; mdp.setContent(text, "text/plain"); //定義MIME類(lèi)型為text/plain,并設(shè)置MimeBodyPart的內(nèi)容。 10. javax.activation.DataHandler JavaMail API不限制信息只為文本,任何形式的信息都可能是MimeMessage的一部分.除了文本信息,文件附件包含在電子郵件信息的一部分是很普遍的,.JavaMail API通過(guò)使用DataHandler對(duì)象,提供一個(gè)允許我們包含非文本BodyPart對(duì)象的簡(jiǎn)便方法. 用法:DataHandler dh = new DataHandler(text, type); mdp.setDatahandler(dh); //mdp是一個(gè)MimeBodyPart對(duì)象 11. javax.activation.FileDataSource FileDataSource對(duì)象可以表示本地文件和服務(wù)器可以直接訪問(wèn)的資源.一個(gè)本地文件可以通過(guò)創(chuàng)建一個(gè)新的MimeBodyPart對(duì)象附在一個(gè)mimeMessage對(duì)象上. 用法::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對(duì)象增加MimeBodyPart 12 .javax.activation.URLDataSource 遠(yuǎn)程資源,URL不會(huì)指向它們,由一個(gè)URLDataSource對(duì)象表示.一個(gè)遠(yuǎn)程資源可以通過(guò)創(chuàng)建一個(gè)新mimeBodyPart對(duì)象附在一個(gè)mimeMessage對(duì)象上(同FileDataSource差不多). 用法::FileDataSource唯一不同的是數(shù)據(jù)源的設(shè)置: 四、用javaMail實(shí)現(xiàn)郵件發(fā)送、讀取步驟 環(huán)境介紹:本例所用的環(huán)境:jdk1.5,eclipse3.1;需導(dǎo)入的包:mail.jar, activation.jar 由於是應(yīng)用程序只需新建一個(gè)java工程,工程目錄結(jié)構(gòu):
![]() 右鍵點(diǎn)擊java工程名javaMailTest選擇內(nèi)容/Properties──點(diǎn)擊java建置路徑──點(diǎn)擊新增外部JAR如圖
![]() 選擇mail和activeation兩個(gè)包。 1.啟動(dòng)郵件服務(wù)器:運(yùn)行http://jakrata.網(wǎng)站下載的james服務(wù)器下的james/bin里的run.bat就可以啟動(dòng)了服務(wù)器如圖:
![]() 在DOS用telnet localhost 4555 登錄郵件服務(wù)器如圖: ![]() Login id: root 輸入root後會(huì)提示輸入密碼
![]() 同樣輸入root可登錄郵件服務(wù)器,用adduser 用戶(hù)名 密碼 命令可添加用戶(hù) 2.郵件系統(tǒng)工作過(guò)程
![]() 3.發(fā)郵件 3.1.用import導(dǎo)入所需要的包:java.util.*; javax.mail.*; avax.mail.internet.*; javax.activation.*; 3.2.創(chuàng)建java.util.Properties對(duì)象並將郵件服務(wù)器、郵件傳輸協(xié)議放入其中,如果需要授權(quán)訪問(wèn)還要存放訪問(wèn)用戶(hù)名、密碼信息。 Properties props = System.getProperties(); props.put("mail.transpost.protocol", "smtp"); props.put("mail.smtp.host", host); 3.3.通過(guò)以上的Properties對(duì)象實(shí)例化一個(gè)會(huì)話Session。 Session session = Session.getDefaultInstance(props, null); 3.4.用MimeMessage類(lèi)通過(guò)創(chuàng)建的Session構(gòu)建一個(gè)消息,並設(shè)置消息提各個(gè)元素如:發(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類(lèi)的send方法發(fā)送構(gòu)建的消息:Transport.send(msg); 3.6.以java應(yīng)用程序方式運(yùn)行應(yīng)用程序mail.java發(fā)送郵件正常會(huì)彈出如下圖框
4.讀郵件 4.1.用import導(dǎo)入所需要的包:java.io.*; java.text.*; avax.mail.internet.*; javax.mail.*; java.util.* 4.2.創(chuàng)建java.util.Properties對(duì)象:Properties props = new Properties(); 4.3.通過(guò)以上的Properties對(duì)象實(shí)例化一個(gè)會(huì)話Session: Session session = Session.getDefaultInstance(props, null); 4.4.通過(guò)Session創(chuàng)建郵件服務(wù)器Store,並指定讀取郵件協(xié)議:Store store = session.getStore("pop3");: 4.5.連接郵件服務(wù)器並傳入服務(wù)器名、用戶(hù)、密碼信息:store.connect(hostname, username, password); 4.6.取得郵件服務(wù)器目錄,對(duì)於用POP3協(xié)議讀取只有“INBOX”目錄: Folder folder = store.getFolder("INBOX"); 4.7.打開(kāi)目錄,並指定郵件讀取方式為只讀、讀寫(xiě)或其它:folder.open(Folder.READ_ONLY); 4.8.讀取這個(gè)用戶(hù)下的所有郵件放在消息數(shù)組裡:Message message[] = folder.getMessages(); 4.9.讀取在消息數(shù)組中的每個(gè)郵件,在讀取郵件需要按照郵件的各個(gè)部分分別讀取,如讀取發(fā)信人、讀取收信人、讀取主題、讀取郵件內(nèi)容、讀取郵件附件等,並且還要根郵件的各個(gè)部分在發(fā)送時(shí)的MIME類(lèi)型編碼進(jìn)行相應(yīng)的解碼。 4.10.以java應(yīng)用程序方式運(yùn)行應(yīng)用程序readMail.java如正常會(huì)交替彈出如下兩個(gè)圖框 並且在控制臺(tái)會(huì)輸出所有郵件信息: ![]() 附源碼:發(fā)送郵件源碼,讀取郵件源碼
1.授權(quán)訪問(wèn) import javax.mail.*; public class Email_Autherticatorbean extends Authenticator { private String m_username = null; //用戶(hù)名 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); //存儲(chǔ)驗(yàn)證的用戶(hù)名、密碼 } }
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); } /** * 開(kāi)始發(fā)送信件 */ public boolean startSend() { Properties props = System.getProperties(); // 創(chuàng)建Properties對(duì)象 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)的會(huì)話對(duì)象 //props.put("mail.smtp.auth", "true"); 用於發(fā) //props.put("mail.smpt.port", "25"); 外部郵 //Email_Autherticatorbean auth = new Email_Autherticatorbean("ypfeng2005", "20052005"); // 驗(yàn)證 件 // session //Session session = Session.getInstance(props, auth); // 得到通過(guò)驗(yàn)證會(huì)話 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!?。?span>"); Multipart mp = new MimeMultipart();// 后面的BodyPart將加入到此處創(chuàng)建的Multipart中 Enumeration efile = file.elements();// 利用枚舉器遍歷集合 // 檢查序列中是否還有更多的對(duì)象 while (efile.hasMoreElements()) { MimeBodyPart mbp = new MimeBodyPart(); // 選擇出每一個(gè)附件名 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對(duì)象 private String dateformat = "yy-MM-dd HH:mm"; // 默認(rèn)的日前顯示格式 /** * * 構(gòu)造函數(shù),初始化一個(gè)MimeMessage對(duì)象 */ public readMail() { } public readMail(MimeMessage mimeMessage) { this.mimeMessage = mimeMessage; System.out.println("create a PraseMimeMessage object........"); } /** * * 獲取一個(gè)MimeMessage對(duì)象 */ 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)容保存到一個(gè)StringBuffer對(duì)象中,解析郵件 * * 主要是根據(jù)MimeType類(lèi)型的不同執(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(); } } /** * * 類(lèi)測(cè)試 */ public static void main(String args[]) throws Exception { String host = "localhost"; // 主機(jī)名/ip String username = "fyc"; // 用戶(hù)名 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]); } } } |
|