JavaMailAPI细节详细解析大全.docx
- 文档编号:25142437
- 上传时间:2023-06-05
- 格式:DOCX
- 页数:23
- 大小:27.53KB
JavaMailAPI细节详细解析大全.docx
《JavaMailAPI细节详细解析大全.docx》由会员分享,可在线阅读,更多相关《JavaMailAPI细节详细解析大全.docx(23页珍藏版)》请在冰豆网上搜索。
JavaMailAPI细节详细解析大全
JavaMailAPI细节详细解析大全
J
avaMailAPI是读取、撰写、发送电子信息的可选包。
我们可用它来建立如Eudora、Foxmail、MSOutlookExpress一般的用户代理程序(MailUserAgent,简称MUA)。
让我们看看JavaMailAPI是如何提供信息访问功能的吧!
JavaMailAPI被设计用于以不依赖协议的方式去发送和接收电子信息,文中着重:
如何以不依赖于协议的方式发送接收电子信息,这也是本文所要描述的.
一、JavaMailAPI简介
JavaMailAPI是读取、撰写、发送电子信息的可选包。
我们可用它来建立如Eudora、Foxmail、MSOutlookExpress一般的用户代理程序(MailUserAgent,简称MUA)。
而不是像sendmail或者其它的传输代理(MailTransferAgent,简称MTA)程序那样可以传送、递送、转发。
从另外一个角度来看,我们这些电子用户日常用MUA程序来读写,而MUA依赖着MTA处理的递送。
在清楚了到MUA与MTA之间的关系后,让我们看看JavaMailAPI是如何提供信息访问功能的吧!
JavaMailAPI被设计用于以不依赖协议的方式去发送和接收电子信息,这个API被分为两大部分:
基本功能:
如何以不依赖于协议的方式发送接收电子信息,这也是本文所要描述的,不过在下文中,大家将看到这只是一厢情愿而已。
第二个部分则是依赖特定协议的,比如SMTP、POP、IMAP、NNTP协议。
在这部分的JavaMailAPI是为了和服务器通讯,并不在本文的容中。
二、相关协议一览
在我们步入JavaMailAPI之前,先看一下API所涉及的协议。
以下便是大家日常所知、所乐于使用的4大信息传输协议:
SMTP
POP
IMAP
MIME
当然,上面的4个协议,并不是全部,还有NNTP和其它一些协议可用于传输信息,但是由于不常用到,所以本文便不提及了。
理解这4个基本的协议有助于我们更好的使用JavaMailAPI。
然而JavaMailAPI是被设计为与协议无关的,目前我们并不能克服这些协议的束缚。
确切的说,如果我们使用的功能并不被我们选择的协议支持,那么JavaMailAPI并不可能如魔术师一样神奇的赋予我们这种能力。
1.SMTP
简单传输协议定义了递送的机制。
在下文中,我们将使用基于Java-Mail的程序与公司或者ISP的SMTP服务器进行通讯。
这个SMTP服务器将转发到接收者的SMTP服务器,直至最后被接收者通过POP或者IMAP协议获取。
这并不需要SMTP服务器使用支持授权的转发,但是却的确要注意SMTP服务器的正确设置(SMTP服务器的设置与JavaMailAPI无关)。
2.POP
POP是一种邮局协议,目前为第3个版本,即众所周知的POP3。
POP定义了一种用户如何获得的机制。
它规定了每个用户使用一个单独的。
大多数人在使用POP时所熟悉的功能并非都被支持,例如查看中的新数量。
而这个功能是微软的Outlook建的,那么就说明微软Outlook之类的客户端软件是通过查询最近收到的来计算新的数量来实现前面所说的功能。
因此在我们使用JavaMailAPI时需要注意,当需要获得如前面所讲的新数量之类的信息时,我们不得不自己进行计算。
3.IMAP
IMAP使用在接收信息的高级协议,目前版本为第4版,所以也被称为IMAP4。
需要注意的是在使用IMAP时,服务器必须支持该协议。
从这个方面讲,我们并不能完全使用IMAP来替代POP,不能期待IMAP在任何地方都被支持。
假如服务器支持IMAP,那么我们的程序将能够具有以下被IMAP所支持的特性:
每个用户在服务器上可具有多个目录,这些目录能在多个用户之间共享。
其与POP相比高级之处显而易见,但是在尝试采取IMAP时,我们认识到它并不是十分完美的:
由于IMAP需要从其它服务器上接收新信息,将这些信息递送给用户,维护每个用户的多个目录,这都为服务器带来了高负载。
并且IMAP与POP的一个不同之处是POP用户在接收时将从服务器上下载,而IMAP允许用户直接访问目录,所以在服务器进行备份作业时,由于每个长期使用此系统的用户所用的目录会占有很大的空间,这将直接导致服务器上磁盘空间暴涨。
4.MIME
MIME并不是用于传送的协议,它作为多用途的扩展定义了容的格式:
信息格式、附件格式等等。
一些RFC标准都涉及了MIME:
RFC822,RFC2045,RFC2046,RFC2047,有兴趣的Matrixer可以阅读一下。
而作为JavaMailAPI的开发者,我们并不需关心这些格式定义,但是这些格式被用在了程序中。
5.NNTP和其它的第三方协议
正因为JavaMailAPI在设计时考虑到与第三方协议实现提供商之间的分离,故我们可以很容易的添加一些第三方协议。
SUN维护着一个第三方协议实现提供商的列表:
java.sun./products/javamail/Third_Party.html,通过此列表我们可以找到所需要的而又不被SUN提供支持的第三方协议:
比如NNTP这个新闻组协议和S/MIME这个安全的MIME协议。
三、安装
1.安装JavaMail
为了使用JavaMailAPI,需要从java.sun./products/javamail/downloads/index.html下载文件名格式为javamail-[version].zip的文件(这个文件中包括了JavaMail实现),并将其中的mail.jar文件添加到CLASSPATH中。
这个实现提供了对SMTP、IMAP4、POP3的支持。
注意:
在安装JavaMail实现之后,我们将在demo目录中发现许多有趣的简单实例程序。
在安装了JavaMail之后,我们还需要安装JavaBeansActivationFramework,因为这个框架是JavaMailAPI所需要的。
如果我们使用J2EE的话,那么我们并无需单独下载JavaMail,因为它存在于J2EE.jar中,只需将J2EE.jar加入到CLASSPATH即可。
2.安装JavaBeansActivationFramework
从java.sun./products/javabeans/glasgow/jaf.html下载JavaBeansActivationFramework,并将其添加到CLASSPATH中。
此框架增加了对任何数据块的分类、以及对它们的处理的特性。
这些特性是JavaMailAPI需要的。
虽然听起来这些特性非常模糊,但是它对于我们的JavaMailAPI来说只是提供了基本的MIME类型支持。
到此为止,我们应当把mail.jar和activation.jar都添加到了CLASSPATH中。
当然如果从方便的角度讲,直接把这两个Jar文件复制到JRE目录的lib/ext目录中也可以。
四、初次认识JavaMailAPI
1.了解我们的JavaMail环境
A.纵览JavaMail核心类结构
打开JavaMail.jar文件,我们将发现在javax.mail的包下面存在着一些核心类:
Session、Message、Address、Authenticator、Transport、Store、Folder。
而且在javax.mail.internet包中还有一些常用的子类。
B.Session
Session类定义了基本的会话。
就像Http会话那样,我们进行收发的工作都是基于这个会话的。
Session对象利用了java.util.Properties对象获得了服务器、用户名、密码信息和整个应用程序都要使用到的共享信息。
Session类的构造方法是私有的,所以我们可以使用Session类提供的getDefaultInstance()这个静态工厂方法获得一个默认的Session对象:
Propertiesprops=newProperties();
//fillpropswithanyinformation
Sessionsession=Session.getDefaultInstance(props,null);
或者使用getInstance()这个静态工厂方法获得自定义的Session:
Propertiesprops=newProperties();
//fillpropswithanyinformation
Sessionsession=Session.getInstance(props,null);
从上面的两个例子中不难发现,getDefaultInstance()和getInstance()方法的第二个参数都是null,这是因为在上面的例子中并没有使用到授权,下文中将对授权进行详细介绍。
从很多的实例看,在对mailserver进行访问的过程中使用共享的Session是足够的,即使是工作在多个用户的模式下也不例外。
C.Message
当我们建立了Session对象后,便可以被发送的构造信息体了。
在这里SUN提供了Message类型来帮助开发者完成这项工作。
由于Message是一个抽象类,大多数情况下,我们使用javax.mail.internet.MimeMessage这个子类,该类是使用MIME类型、MIME信息头的信息。
信息头只能使用US-ASCII字符,而非ASCII字符将通过编码转换为ASCII的方式使用。
为了建立一个MimeMessage对象,我们必须将Session对象作为MimeMessage构造方法的参数传入:
MimeMessagemessage=newMimeMessage(session);
注意:
对于MimeMessage类来讲存在着多种构造方法,比如使用输入流作为参数的构造方法。
在建立了MimeMessage对象后,我们需要设置它的各个part,对于MimeMessage类来说,这些part就是MimePart接口。
最基本的设置信息容的方法就是通过表示信息容和米么类型的参数调用setContent()方法:
message.setContent("Hello","text/plain");
然而,如果我们所使用的MimeMessage息容是文本的话,我们便可以直接使用setText()方法来方便的设置文本容。
message.setText("Hello");
前面所讲的两种方法,对于文本信息,后者更为合适。
而对于其它的一些信息类型,比如HTML信息,则要使用前者。
别忘记了,使用setSubject()方法对设置主题:
message.setSubject("First");
D.Address
到这里,我们已经建立了Session和Message,下面将介绍如何使用地址类:
Address。
像Message一样,Address类也是一个抽象类,所以我们将使用javax.mail.internet.InternetAddress这个子类。
通过传入代表地址的字符串,我们可以建立一个地址类:
Addressaddress=newInternetAddress("presidentwhitehouse.gov");
如果要在地址后面增加名字的话,可以通过传递两个参数:
代表地址和名字的字符串来建立一个具有地址和名字的地址类:
Addressaddress=newInternetAddress("presidentwhitehouse.gov","GeorgeBush");
本文在这里所讲的地址类是为了设置信息的发信人和收信人而准备的,在建立了地址类后,我们通过message的setFrom()和setReplyTo()两种方法设置的发信人:
message.setFrom(address);
message.setReplyTo(address);
若在中存在多个发信人地址,我们可用addForm()方法增加发信人:
Addressaddress[]=...;
message.addFrom(address);
为了设置收信人,我们使用addRecipient()方法增加收信人,此方法需要使用Message.RecipientType的常量来区分收信人的类型:
message.addRecipient(type,address)
下面是Message.RecipientType的三个常量:
Message.RecipientType.TO
Message.RecipientType.CC
Message.RecipientType.BCC
因此,如果我们要发送给总统,并发用一个副本给第一夫人的话,下面的方法将被用到:
AddresstoAddress=newInternetAddress("vice.presidentwhitehouse.gov");
AddressccAddress=newInternetAddress("first.ladywhitehouse.gov");
message.addRecipient(Message.RecipientType.TO,toAddress);
message.addRecipient(Message.RecipientType.CC,ccAddress);
JavaMailAPI并没有提供检查地址有效性的机制。
当然我们可以自己完成这个功能:
验证地址的字符是否按照RFC822规定的格式书写或者通过DNS服务器上的MX记录验证等。
E.Authenticator
像类那样,JavaMailAPI通过使用授权者类(Authenticator)以用户名、密码的方式访问那些受到保护的资源,在这里“资源”就是指服务器。
在javax.mail包中可以找到这个JavaMail的授权者类(Authenticator)。
在使用Authenticator这个抽象类时,我们必须采用继承该抽象类的方式,并且该继承类必须具有返回PasswordAuthentication对象(用于存储认证时要用到的用户名、密码)getPasswordAuthentication()方法。
并且要在Session中进行注册,使Session能够了解在认证时该使用哪个类。
下面代码片断中的MyAuthenticator就是一个Authenticator的子类。
Propertiesprops=newProperties();
//fillpropswithanyinformation
Authenticatorauth=newMyAuthenticator();
Sessionsession=Session.getDefaultInstance(props,auth);
F.Transport
在发送信息时,Transport类将被用到。
这个类实现了发送信息的协议(通称为SMTP),此类是一个抽象类,我们可以使用这个类的静态方法send()来发送消息:
Transport.send(message);
当然,方法是多样的。
我们也可由Session获得相应协议对应的Transport实例。
并通过传递用户名、密码、服务器主机名等参数建立与服务器的连接,并使用sendMessage()方法将信息发送,最后关闭连接:
message.saveChanges();//implicitwithsend()
Transporttransport=session.getTransport("smtp");
transport.connect(host,username,password);
transport.sendMessage(message,message.getAllRecipients());
transport.close();
评论:
上面的方法是一个很好的方法,尤其是在我们在同一个服务器上发送多个时。
因为这时我们将在连接服务器后连续发送,然后再关闭掉连接。
send()这个基本的方法是在每次调用时进行与服务器的连接的,对于在同一个服务器上发送多个来讲可谓低效的方式。
注意:
如果需要在发送过程中监控mail命令的话,可以在发送前设置debug标志:
session.setDebug(true)。
G.Store和Folder
接收和发送很类似都要用到Session。
但是在获得Session后,我们需要从Session中获取特定类型的Store,然后连接到Store,这里的Store代表了存储的服务器。
在连接Store的过程中,极有可能需要用到用户名、密码或者Authenticator。
//Storestore=session.getStore("imap");
Storestore=session.getStore("pop3");
store.connect(host,username,password);
在连接到Store后,一个Folder对象即目录对象将通过Store的getFolder()方法被返回,我们可从这个Folder中读取信息:
Folderfolder=store.getFolder("INBOX");
folder.open(Folder.READ_ONLY);
Messagemessage[]=folder.getMessages();
上面的例子首先从Store中获得INBOX这个Folder(对于POP3协议只有一个名为INBOX的Folder有效),然后以只读(Folder.READ_ONLY)的方式打开Folder,最后调用Folder的getMessages()方法得到目录中所有Message的数组。
注意:
对于POP3协议只有一个名为INBOX的Folder有效,而对于IMAP协议,我们可以访问多个Folder(想想前面讲的IMAP协议)。
而且SUN在设计Folder的getMessages()方法时采取了很智能的方式:
首先接收新列表,然后再需要的时候(比如读取容)才从服务器读取容。
在读取时,我们可以用Message类的getContent()方法接收或是writeTo()方法将保存,getContent()方法只接收容(不包含头),而writeTo()方法将包括头。
System.out.println(((MimeMessage)message).getContent());
在读取容后,别忘记了关闭Folder和Store。
folder.close(aBoolean);
store.close();
传递给Folder.close()方法的boolean类型参数表示是否在删除操作后更新Folder。
H.继续向前进!
在讲解了以上的七个JavaMail核心类定义和理解了简单的代码片断后,下文将详细讲解怎样使用这些类实现JavaMailAPI所要完成的高级功能。
五、使用JavaMailAPI
在明确了JavaMailAPI的核心部分如何工作后,本人将带领大家学习一些使用JavaMailAPI任务案例。
1.发送
在获得了Session后,建立并填入信息,然后发送它到服务器。
这便是使用JavaMailAPI发送的过程,在发送之前,我们需要设置SMTP服务器:
通过设置Properties的mail.smtp.host属性。
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结构块中。
2.接收
为了在读取,我们获得了session,并且连接到了的相应store,打开相应的Folder,然后得到我们想要的,当然别忘记了在结束时关闭连接。
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(); 上面的代码所作的是从中读取每个,并且显示的发信人地址和主题。 从技术角度讲,这里存在着一个异常的可能: 当发信人地址为空时,getFrom()[0]将抛出异常。 下面的代码片断有效的说明了如何读取容,在显示每个发信人和主题后,将出现用户提示从而得到用户是否读取该的确认,如果输入YES的话,我们可用Message.writeTo(java.io.OutputStreamos)方法将容输出到控制台上,关于Message.writeTo()的具体用法请看JavaMailAPI。 BufferedReaderreader=newB
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- JavaMailAPI 细节 详细 解析 大全