我干軟件開(kāi)發(fā)也有一點(diǎn)的年頭了,回頭想想,也經(jīng)歷了不少的酸甜苦辣,為解決了復(fù)雜的問(wèn)題快樂(lè)過(guò).也為不分晝夜的加班趕工
程郁悶過(guò).不過(guò)這些都沒(méi)能減少我對(duì)計(jì)算機(jī)的熱情,我對(duì)程序的喜好.以前對(duì)JavaMail也有一些學(xué)習(xí)性的認(rèn)識(shí),不過(guò)一直沒(méi)在實(shí)際的項(xiàng)目中應(yīng)用過(guò).直到最
近的一個(gè)項(xiàng)目,需要JavaMail所以我打算認(rèn)真的學(xué)習(xí)一下這種技術(shù),因?yàn)槲夷壳吧瞄L(zhǎng)的是Struts,而Struts又不具備郵件發(fā)送的功能,所以我
要深刻的學(xué)習(xí)一下JavaMailAPI.所以在我學(xué)會(huì)了JavaMail的基本操作的同時(shí)也將這篇文章獻(xiàn)給大家,雖然技術(shù)含量不高,但是希望能對(duì)一些剛
剛接觸JavaMail的同道中人有所幫助.好了閑話少說(shuō)進(jìn)入正題,首先介紹幾個(gè)郵件傳輸協(xié)議,雖然說(shuō)不了解這些協(xié)議也可以實(shí)用JavaMailAPI,
但是我始終認(rèn)為,如果不透徹的了解一種技術(shù)的本質(zhì),即使會(huì)用了也是照葫蘆畫(huà)瓢,換一種模式也許就玩不轉(zhuǎn)了.
??? SMTP:
簡(jiǎn)單郵件傳輸協(xié)議(Simple Mail Transfer
Protocol,SMTP)由RFC821定義,它定義了發(fā)送郵件的機(jī)制,在JavaMail環(huán)境中,基于JavaMail的程序?qū)⒑鸵蛱鼐W(wǎng)服務(wù)供應(yīng)商
ISP(internet Service Provider
’
s)SMTP服務(wù)器通信.SMTP服務(wù)器會(huì)中轉(zhuǎn)消息給接收方SMTP服務(wù)器以便最終讓用戶經(jīng)由POP或者IMAP獲得.
??? POP:
代表郵局協(xié)議(Post Office
Protocol).目前的版本是3.所以一般都稱之為POP3.這個(gè)協(xié)議是由RFC1939定義的.POP是一種機(jī)制,因特網(wǎng)上多大數(shù)用戶用它得到郵
件.它規(guī)定每個(gè)用戶一個(gè)郵箱的支持.使用POP協(xié)議的時(shí)候,用戶的許多性能并不是由POP協(xié)議支持的,如查看幾封新郵件消息這個(gè)功能,這些功能內(nèi)建在如
Eudora或MicrosoftOutlook之類的程序中,它們記住一些事.所以在用JavaMail的時(shí)候,如果你想要這些信息,你就必須自己算
了.
??? IMAP:
是更高級(jí)的用戶接收消息的協(xié)議,被定義在RFC2060中,IMAP代表因特網(wǎng)消息訪問(wèn)協(xié)議(Internet Message Access
Protocol),目前用的版本是4,所以也叫做IMAP4.在用到IMAP的時(shí)候,郵件服務(wù)器必須支持這個(gè)協(xié)議,不能僅僅把使用POP的程序用于
IMAP,并指望它支持IMAP所有性能.
??? MIME:是因特網(wǎng)郵件擴(kuò)展標(biāo)準(zhǔn)(Multipurpose Internet Mail Extensions).它不是郵件傳輸協(xié)議,但是對(duì)于傳輸?shù)膬?nèi)容的消息,附件以及其他的內(nèi)容定義了格式.可以理解成一個(gè)定義合適的標(biāo)準(zhǔn).
???
NNTP:因?yàn)镴avaMail將供應(yīng)商和所有其它的東西分開(kāi)了,您就能輕松添加額外的協(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即可.
??? 如果實(shí)用J2EE就沒(méi)由什么特定非要用基本的JavaMailAPI了.J2EE的類就能處理了.只要確保j2ee.jar文件在classpath中就Ok了.
下面我用一個(gè)最簡(jiǎn)單的例子還演示第一條消息的發(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對(duì)象.
Session session = Session.getDefaultInstance(props,null);
4,從Session創(chuàng)建一個(gè)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,在編譯用運(yùn)的時(shí)候傳遞MSTP服務(wù)器,from地址,to地址.
??? 通過(guò)簡(jiǎn)單的接觸了JavaMail相信大家多郵件發(fā)送也有了簡(jiǎn)單的了解和認(rèn)識(shí),下面我主要研究一下它的具體功能,也就是說(shuō)具體的接口或類的含義.
??? Session
類定義了一個(gè)基本的郵件會(huì)話,所有的其他類都是由這個(gè)session才得意生效的,Session對(duì)象用java.util.Properties對(duì)象獲
取信息,如郵件服務(wù)器,用戶名,密碼及整個(gè)應(yīng)用程序中共享的其他信息.類的構(gòu)造器是此有的,private.它能用getDefaultInstance
()方法來(lái)共享.獲取Session對(duì)象的方方法如下:
Properties props = new Properties();
Session session = Session.getDefaultInstance(props,null);
Null參數(shù)都是Authenticator對(duì)象,在這里沒(méi)有使用.
對(duì)于大多數(shù)情況,共享的session已經(jīng)足夠用了.
??? Message
消息類,在獲得了Session對(duì)象后,就可以繼續(xù)創(chuàng)建要發(fā)送的消息.因?yàn)镸essage是個(gè)抽象類,您必須用一個(gè)子類,多數(shù)情況下為
java.mail.internet.MimeMessage.這個(gè)能理解成MIME類型和頭的電子郵件消息.正如不同的RFC中定義的,雖然在某些頭
部域非ASCII字符也能被編譯,但是Message頭只能被限制用US-ASCII字符.要?jiǎng)?chuàng)建一個(gè)Message請(qǐng)將Session對(duì)象傳遞給
MimeMessage的構(gòu)造器.
MimeMessage message = newMimeMessage(session);
一旦獲得消息,就可以設(shè)置各個(gè)部分了.最基本的就是setContent()方法,例如/
message.setContent(
“
Hello
”
,
”
text/plain
”
);
如果知道在實(shí)用MimeMessage,而且消息是純文本格式,就可以用setText()方法,它只需要代表實(shí)際內(nèi)容的參數(shù).(Mime類型缺省為text/plain)
用setSubject()方法設(shè)置subject(主題);
message.setSubject(
“
主題
”
);
??? Address地址類,和Message一樣也是一個(gè)抽象類,一旦創(chuàng)建了Session和Message并將內(nèi)容填入消息后,就可以用Address確定信件的地址了,用javax.mail.internet.
InternetAddress類.若創(chuàng)建的地址只包含電子郵件地址,只要傳遞電子郵件地址給構(gòu)造器就可以了.例如:Address address = new InternetAddress(
“
it5719@163.com
”
);
若希望名字挨著電子郵件現(xiàn)實(shí),就可以把它傳遞給構(gòu)造器,如下:
Address address = new InternetAddress(
“
it5719@163.com
”
,
”
我心依舊
”
);
需要為消息的from
域和to域創(chuàng)建地址對(duì)象,除非郵件服務(wù)器阻止,沒(méi)有什么能阻止你發(fā)送一段看上去是任何人的消息了呵呵.一旦創(chuàng)建address將他們域消息連接方法有兩
種,如要要識(shí)別發(fā)件人的就可以用setFrom()和setReplyTo方法.然后message.setFrom(address);
需要實(shí)用多個(gè)from地址的就用addFrom()方法.例子如下:
Address[] address = ,.,. ;??? message.addFrom(address);
若要識(shí)別消息recipient收件人,就要實(shí)用addRecipient()方法了.例如:
message.addRecipient(type,address)
??? Authenticator
與java.net類一樣,JavaMailAPI也可以利用Authentcator通過(guò)用戶名密碼訪問(wèn)受保護(hù)的資源.對(duì)于JavaMail來(lái)說(shuō),這些
資源就是郵件服務(wù)器,Authentcator類在javax.mail包中.要使用Authenticator,首先創(chuàng)建一個(gè)抽象的子類,并從
GetPasswordAuthentication
方法中返回passwordAuthentication實(shí)例,創(chuàng)建完成后,您必須向session注冊(cè)Authenticator,然后在需要認(rèn)證的時(shí)
候會(huì)通知它,其實(shí)說(shuō)白了就是把配置的用戶名和密碼返回給調(diào)用它的程序.例如:
Properties props = new properties();
Authenticator auth = new MailAuthenticator()//接口聲明,創(chuàng)建自己新類的實(shí)例.
Session session = Session.getDefauItInstance(props,auth);
??? Transport消息發(fā)送傳輸類,這個(gè)類用協(xié)議指定的語(yǔ)言發(fā)送消息,通常是SMTP,它是抽象類,它的工作方式與Session有些類似,盡調(diào)用靜態(tài)方法send()方法,就OK了.例如:
Transport.send(message);
或者也可以從針對(duì)協(xié)議的會(huì)話中獲取一個(gè)特定的實(shí)例,傳遞用戶名和密碼.發(fā)送消息,然后關(guān)閉連接,例如:
message.saveChanges();
transport transport = session.getTreansport(
“
smtp
”
);//指定的協(xié)議
transport.connect(host,username,password);
transport.sendMessage(message,message.getAllRecipients());
transport.close();
如果要觀察傳到郵件服務(wù)器上的郵件命令,請(qǐng)用session.setDubug(true)設(shè)置調(diào)試標(biāo)志.
??? Store和folder用session獲取消息,與發(fā)送消息開(kāi)始很相似,但是在session得到后,很可能實(shí)用用戶名和密碼或?qū)嵱肁uthenticator連接到一個(gè)Store.類似于Transport,也是一樣要告訴store用什么協(xié)議.例如
Store store = session.getStore(
“
pop3
”
);
Store.connect(host,username,password);
連接到Store之后,接下來(lái),獲得一個(gè)folder,必須打開(kāi)它就可以讀取里邊的消息了.
Folder folder = store.getFolder("INBOX");
folder.open(Folder.READ_ONLY);
Message[] message = folder.getMessages();
POP3唯一可用的文件夾就是INBOX,如果實(shí)用IMAP,還可以用其他的文件夾.
當(dāng)讀到了具體的message以后,就可以用getContent來(lái)獲取內(nèi)容,或者用writeTo()將內(nèi)容寫(xiě)入流,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郵件操作的基本的常用類,我覺(jué)得理解了這幾個(gè)類的機(jī)制,基本就可以處理一般的郵件操作了.下面是一個(gè)我寫(xiě)的JavaMail實(shí)現(xiàn)郵件發(fā)送的代碼.
首先是一個(gè)Authenticator類的實(shí)現(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);
??? }
?
}
?
這個(gè)類是發(fā)送郵件的類.
?
?
package com.deepdo.common.mail;
?
/**
?* 此處插入類型說(shuō)明。
?* 創(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主機(jī)地址
??? 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("沒(méi)有指定發(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("沒(méi)有指定收件人郵件地址!");
???
??????? 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());
??? }
??? /**
???
?* 此處插入方法說(shuō)明。
???
?*/
??? public void init()
??? {
???
??? }
??? /**
???
?* 發(fā)送e_mail,返回類型為int
???
?* 當(dāng)返回值為0時(shí),說(shuō)明郵件發(fā)送成功
???
?* 當(dāng)返回值為3時(shí),說(shuō)明郵件發(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ù)器錯(cuò)誤:");
???
?????
??????return 3;
???
??????? } catch (MessagingException e) {
???
??????????? System.out.println("連接郵件服務(wù)器錯(cuò)誤:");
???
??????????? 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();
??????? }
??? }
}
?
Trackback: http://tb.blog.csdn.net/TrackBack.aspx?PostId=1565935
附:Groovy輕松入門(mén)——Grails實(shí)戰(zhàn)之GORM篇
posted on 2007-04-18 21:23
山風(fēng)小子 閱讀(763)
評(píng)論(0) 編輯 收藏 所屬分類:
JavaMail