javaMail笔记.docx

上传人:b****5 文档编号:8837131 上传时间:2023-05-15 格式:DOCX 页数:24 大小:29.02KB
下载 相关 举报
javaMail笔记.docx_第1页
第1页 / 共24页
javaMail笔记.docx_第2页
第2页 / 共24页
javaMail笔记.docx_第3页
第3页 / 共24页
javaMail笔记.docx_第4页
第4页 / 共24页
javaMail笔记.docx_第5页
第5页 / 共24页
javaMail笔记.docx_第6页
第6页 / 共24页
javaMail笔记.docx_第7页
第7页 / 共24页
javaMail笔记.docx_第8页
第8页 / 共24页
javaMail笔记.docx_第9页
第9页 / 共24页
javaMail笔记.docx_第10页
第10页 / 共24页
javaMail笔记.docx_第11页
第11页 / 共24页
javaMail笔记.docx_第12页
第12页 / 共24页
javaMail笔记.docx_第13页
第13页 / 共24页
javaMail笔记.docx_第14页
第14页 / 共24页
javaMail笔记.docx_第15页
第15页 / 共24页
javaMail笔记.docx_第16页
第16页 / 共24页
javaMail笔记.docx_第17页
第17页 / 共24页
javaMail笔记.docx_第18页
第18页 / 共24页
javaMail笔记.docx_第19页
第19页 / 共24页
javaMail笔记.docx_第20页
第20页 / 共24页
亲,该文档总共24页,到这儿已超出免费预览范围,如果喜欢就下载吧!
下载资源
资源描述

javaMail笔记.docx

《javaMail笔记.docx》由会员分享,可在线阅读,更多相关《javaMail笔记.docx(24页珍藏版)》请在冰点文库上搜索。

javaMail笔记.docx

javaMail笔记

JavaMail API简介

SMTP

简单邮件传输协议(SimpleMailTransferProtocol,SMTP)由RFC821定义。

它定义了发送电子邮件的机制。

在JavaMailAPI环境中,您基于JavaMail的程序将和您的公司或因特网服务供应商的(InternetServiceProvider's,ISP's)SMTP服务器通信。

SMTP服务器会中转消息给接收方SMTP服务器以便最终让用户经由POP或IMAP获得。

这不是要求SMTP服务器成为开放的中继,尽管SMTP服务器支持身份验证,不过还是得确保它的配置正确。

像配置服务器来中继消息或添加删除邮件账号这类任务的实现,JavaMailAPI中并不支持。

POP

POP代表邮局协议(PostOfficeProtocol)。

目前用的是版本3,也称POP3,RFC1939定义了这个协议。

POP是一种机制,因特网上大多数人用它得到邮件。

它规定每个用户一个邮箱的支持。

这就是它所能做的,而这也造成了许多混淆。

使用POP时,用户熟悉的许多性能并不是由POP协议支持的,如查看有几封新邮件消息这一性能。

这些性能内建于如Eudora或MicrosoftOutlook之类的程序中,它们能记住一些事,诸如最近一次收到的邮件,还能计算出有多少是新的。

所以当使用JavaMailAPI时,如果您想要这类信息,您就必须自己算。

IMAP

IMAP是更高级的用于接收消息的协议。

在RFC2060中被定义,IMAP代表因特网消息访问协议(InternetMessageAccessProtocol),目前用的是版本4,也称IMAP4。

在用到IMAP时,邮件服务器必需支持这个协议。

不能仅仅把使用POP的程序用于IMAP,并指望它支持IMAP所有性能。

假设邮件服务器支持IMAP,基于JavaMail的程序可以利用这种情况―用户在服务器上有多个文件夹(folder),并且这些文件夹可以被多个用户共享。

因为有这一更高级的性能,您也许会认为所有用户都会使用IMAP。

事实并不是这样。

要求服务器接收新消息,在用户请求时发送到用户手中,还要在每个用户的多个文件夹中维护消息。

这样虽然能将消息集中备份,但随着用户长期的邮件夹越来越大,到磁盘空间耗尽时,每个用户都会受到损失。

使用POP,就能卸载邮件服务器上保存的消息了。

NNTP

因为JavaMailAPI将供应商和所有其它的东西分开了,您就能轻松添加额外的协议支持。

Sun保留了一张第三方供应商列表,他们利用了Sun不提供超出(out-of-the-box)支持范围的协议。

您会找到NNTP(网络新闻传输协议)[新闻组]、S/MIME(安全多用途因特网邮件扩展)及其它支持。

MIME

MIME代表多用途因特网邮件扩展标准(MultipurposeInternetMailExtensions)。

它不是邮件传输协议。

但对传输内容的消息、附件及其它的内容定义了格式。

这里有很多不同的有效文档:

RFC822、RFC2045、RFC2046和RFC2047。

作为一个JavaMailAPI的用户,您通常不必对这些格式操心。

无论如何,一定存在这些格式而且程序会用到它。

JavaMailAPI的核心类:

Session、Message、Address、Authenticator、Transport、Store和Folder

Session对象

Session类定义了一个基本邮件会话(session)。

所有其它类都是经由这个session才得以生效。

Session对象用java.util.Properties对象获取信息,如邮件服务器、用户名、密码及整个应用程序中共享的其它信息。

类的构造器是私有的(private)。

您可以得到单个缺省session,它能用getDefaultInstance()方法被共享:

Propertiesprops=newProperties();

//fillpropswithanyinformation

Sessionsession=Session.getDefaultInstance(props,null);

或者,您还可以用getInstance()创建一个独立的session:

Propertiesprops=newProperties();

//fillpropswithanyinformation

Sessionsession=Session.getDefaultInstance(props,null);

对于这两种情况,null参数都是Authenticator对象(在这次没有使用)。

对于大多数情况,共享的session已经够用了,即使要处理多个用户邮箱的邮件session也一样。

您可以在通信过程中稍后的步骤加入用户名和密码组合,让一切保持独立。

Message对象

一旦获得Session对象,就可以继续创建要发送的消息。

这由Message类来完成。

因为Message是个抽象类,您必需用一个子类,多数情况下为javax.mail.internet.MimeMessage。

MimeMessage是个能理解MIME类型和头的电子邮件消息,正如不同RFC中所定义的。

虽然在某些头部域非ASCII字符也能被译码,但Message头只能被限制为用US-ASCII字符。

要创建一个Message,请将Session对象传递给MimeMessage构造器:

MimeMessagemessage=newMimeMessage(session);

注意:

还存在其它构造器,如用按RFC822格式的输入流来创建消息。

一旦获得消息,您就可以设置各个部分,因为Message实现Part接口(且MimeMessage实现MimePart)。

设置内容的基本机制是setContent()方法,同时使用参数,分别代表内容和mime类型:

message.setContent("Hello","text/plain");

但如果,您知道您在使用MimeMessage,而且消息是纯文本格式,您就可以用setText()方法,它只需要代表实际内容的参数,(MIME类型缺省为text/plain):

message.setText("Hello");//注意不要采用这表示1个信封应该使用上面的方法

后一种格式是设置纯文本消息内容的首选机制。

至于发送其它类型的消息,如HTML文件格式的消息,我们首选前者。

用setSubject()方法设置subject(主题):

message.setSubject("First");

Address对象

一旦您创建了Session和Message,并将内容填入消息后,就可以用Address确定信件地址了。

和Message一样,Address也是个抽象类。

您用的是javax.mail.internet.InternetAddress类。

若创建的地址只包含电子邮件地址,只要传递电子邮件地址到构造器就行了。

Addressaddress=newInternetAddress("president@whitehouse.gov");

若希望名字紧挨着电子邮件显示,也可以把它传递给构造器:

Addressaddress=newInternetAddress("president@whitehouse.gov","GeorgeBush");

需要为消息的from域和to域创建地址对象。

除非邮件服务器阻止,没什么能阻止你发送一段看上去是来自任何人的消息。

一旦创建了address(地址),将它们与消息连接的方法有两种。

如果要识别发件人,您可以用setFrom()和setReplyTo()方法。

message.setFrom(address)

需要消息显示多个from地址,可以使用addFrom()方法:

Addressaddress[]=...;

message.addFrom(address);

若要识别消息recipient(收件人),您可以使用addRecipient()方法。

除address(地址)外,这一方法还请求一个Message.RecipientType。

message.addRecipient(type,address)

三种预定义的地址类型是:

Message.RecipientType.TO主要发送

Message.RecipientType.CC抄送

Message.RecipientType.BCC匿名发送

如果消息是发给副总统的,同时发送一个副本(carboncopy)给总统夫人,以下做法比较恰当:

AddresstoAddress=newInternetAddress("vice.president@whitehouse.gov");

AddressccAddress=newInternetAddress("first.lady@whitehouse.gov");

message.addRecipient(Message.RecipientType.TO,toAddress);

message.addRecipient(Message.RecipientType.CC,ccAddress);

JavaMailAPI没有提供电子邮件地址有效性核查机制。

虽然通过编程,自己能够扫描有效字符(如RFC822中定义的)或验证邮件交换(mailexchange,MX)记录,但这些功能不属于JavaMailAPI。

Authenticator对象验证作用

与类一样,JavaMailAPI也可以利用Authenticator通过用户名和密码访问受保护的资源。

对于JavaMailAPI来说,这些资源就是邮件服务器。

JavaMailAuthenticator在javax.mail包中,而且它和中同名的类Authenticator不同。

两者并不共享同一个Authenticator,因为JavaMailAPI用于Java1.1,它没有类别。

要使用Authenticator,先创建一个抽象类的子类,并从getPasswordAuthentication()方法中返回PasswordAuthentication实例。

创建完成后,您必需向session注册Authenticator。

然后,在需要认证的时候,就会通知Authenticator。

您可以弹出窗口,也可以从配置文件中(虽然没有加密是不安全的)读取用户名和密码,将它们作为PasswordAuthentication对象返回给调用程序。

Propertiesprops=newProperties();

//fillpropswithanyinformation

Authenticatorauth=newMyAuthenticator();

Sessionsession=Session.getDefaultInstance(props,auth);

Transport发送对象

消息发送的最后一部分是使用Transport类。

这个类用协议指定的语言发送消息(通常是SMTP)。

它是抽象类,它的工作方式与Session有些类似。

仅调用静态send()方法,就能使用类的缺省版本:

Transport.send(message);

或者,您也可以从针对您的协议的会话中获得一个特定的实例,传递用户名和密码(如果不必要就不传),发送消息,然后关闭连接。

message.saveChanges();//implicitwithsend()

Transporttransport=session.getTransport("smtp");

transport.connect(host,username,password);

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

transport.close();

后面这种方法在您要发送多条消息时最好,因为它能保持邮件服务器在消息间的活动状态。

基本send()机制为每个方法的调用设置与服务器独立的连接。

注意:

要观察传到邮件服务器上的邮件命令,请用session.setDebug(true)设置调试标志。

 

Store和folder存储对象和文件夹对象

用Session获取消息与发送消息开始很相似。

但是,在session得到后,很可能使用用户名和密码或使用Authenticator连接到一个Store。

类似于Transport,您告知Store使用什么协议:

//Storestore=session.getStore("imap");

Storestore=session.getStore("pop3");

store.connect(host,username,password);

连接到Store之后,接下来,您就可以获取一个Folder,您必需先打开它,然后才能读里面的消息。

Folderfolder=store.getFolder("INBOX");

folder.open(Folder.READ_ONLY);

Messagemessage[]=folder.getMessages();

POP3唯一可以用的文件夹是INBOX。

如果使用IMAP,还可以用其它文件夹。

注意:

Sun的供应商有意变得聪明。

虽然Messagemessage[]=folder.getMessages();看上去是个很慢的操作,它从服务器上读取每一条消息,但仅在你实际需要消息的一部分时,消息的内容才会被检索。

一旦有了要读的Message,您可以用getContent()来获取其内容,或者用writeTo()将内容写入流。

getContent()方法只能得到消息内容,而writeTo()的输出却包含消息头。

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

一旦读完邮件,要关闭与folder和store的连接。

folder.close(aBoolean);

store.close();

传递给folder的close()方法的boolean表示是否清除已删除的消息从而更新folder。

案例说明

发送消息

发送电子邮件消息这一过程包括获取一个会话,创建并填充一则消息,然后发送。

得到Session时,经由设置传递的Properties对象中的mail.smtp.host属性,可以指定您的SMTP服务器:

Stringhost=...;

Stringfrom=...;

Stringto=...;

//Getsystemproperties

Propertiesprops=System.getProperties();

//Setupmailserver

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

//Getsession

Sessionsession=Session.getDefaultInstance(props,null);

//Definemessage

MimeMessagemessage=newMimeMessage(session);

message.setFrom(newInternetAddress(from));

message.addRecipient(Message.RecipientType.TO,

newInternetAddress(to));

message.setSubject("HelloJavaMail");

message.setText("WelcometoJavaMail");

//Sendmessage

Transport.send(message);

您应该将代码放在一个try-catch程序块中,这样创建和发送消息时就能够抛出异常。

消息的提取

为读邮件,您获取一个会话,获取并连接一个用于邮箱的适宜的存储(store),打开适宜的文件夹,然后获取您的消息。

同样,切记完成后关闭连接。

Stringhost=...;

Stringusername=...;

Stringpassword=...;

//Createemptyproperties

Propertiesprops=newProperties();

//Getsession

Sessionsession=Session.getDefaultInstance(props,null);

//Getthestore

Storestore=session.getStore("pop3");

store.connect(host,username,password);

//Getfolder

Folderfolder=store.getFolder("INBOX");

folder.open(Folder.READ_ONLY);

//Getdirectory

Messagemessage[]=folder.getMessages();

for(inti=0,n=message.length;i

System.out.println(i+":

"+message[i].getFrom()[0]

+"\t"+message[i].getSubject());

}

//Closeconnection

folder.close(false);

store.close();

对每条消息做些什么由您决定。

上面的代码块只是显示这些消息的发件人和主题。

技术上讲,from地址列表可能为空,而getFrom()[0]调用会抛出一个异常。

要显示全部信息,您可以在用户看完from和subject域之后给出提示,如用户有需要,就调用消息的writeTo()方法来实现。

BufferedReaderreader=newBufferedReader(

newInputStreamReader(System.in));

//Getdirectory

Messagemessage[]=folder.getMessages();

for(inti=0,n=message.length;i

System.out.println(i+":

"+message[i].getFrom()[0]

+"\t"+message[i].getSubject());

System.out.println("Doyouwanttoreadmessage?

"+

"[YEStoread/QUITtoend]");

Stringline=reader.readLine();

if("YES".equals(line)){

message[i].writeTo(System.out);

}elseif("QUIT".equals(line)){

break;

}

}

消息和标志的删除

消息的删除涉及使用与消息相关的Flags(标志)。

不同flag对应不同的状态,有些由系统定义而有些则由用户定义。

下面列出在内部类Flags.Flag中预定义的标志:

∙Flags.Flag.ANSWERED

∙Flags.Flag.DELETED

∙Flags.Flag.DRAFT

∙Flags.Flag.FLAGGED

∙Flags.Flag.RECENT

∙Flags.Flag.SEEN

∙Flags.Flag.USER

仅仅因为存在一个标志,并不意味着所有邮件服务器或供应商都支持这个标志。

例如,除了删除消息标志外,POP协议不再支持其它任何标志。

检查是否存在新邮件,这不是个POP任务,而是内建于邮件客户机的任务。

为找出哪些标志能被支持,可以用getPermanentFlags()向folder提出要求。

要删除消息,您可以设置消息的DELETEDflag:

message.setFlag(Flags.Flag.DELETED,true);

首先,请以READ_WRITE模式打开folder:

folder.open(Folder.READ_WRITE);

然后,当所有消息的处理完成后,关闭folder,并传递一个true值,从而擦除(expunge)有delete标志的消息。

folder.close(true);

一个Folder的expunge()方法可以用来删除消息。

但Sun的POP3供应商不支持。

其它供应商有的或许能够实现这一功能,而有的则不能。

IMAP供应商极有可能实现此功能。

因为POP只支持单个对邮箱的访问,对Sun的供应商来说,您必需关闭folder以删除消息。

要取消标志,只要传递false给setFlag()方法就行了。

想知道是否设置过标志,可以用isSet()检查。

认证

您已经知道―如果需要可以用一个Authenticator提示用户输入用户名和密码,而不是将用户名和密码作为字符串传递。

在这里您会明确了解怎样更充分的使用认证。

不用主机、用户名和密码与Store相连接,而是设置Properties来拥有主机,然后告诉Session自定义的Authenticator实例,如下所示:

//Setupproperties

Propertiesprops=System.getProperties();

props.put("mail.pop3.host",host);

//Setupauthentication,getsession

Authenticatorauth=newPopupAuthenticator();

Sessionsession=Session.getDefaultInstance(props,auth);

//Getthestore

Storestore=session.getStore("pop3");

store.connect();

然后,您创建一个Authenticator子类并从getPasswordAuthentication()

展开阅读全文
相关资源
猜你喜欢
相关搜索

当前位置:首页 > 幼儿教育 > 家庭教育

copyright@ 2008-2023 冰点文库 网站版权所有

经营许可证编号:鄂ICP备19020893号-2