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大信息传输协议:SMTPPOPIMAPMIME当然,上面的4个协议,并不是全部,还有NNTP和其它一些协议可用于传输信息,但是由于不常用到,所以本文便不提及了。理解这4个基本的协议有助于我们更好的使用JavaMailAPI。然而JavaMailAPI是被设计为与协议无关的,目前我们并不能克服这些协议的束缚。确切的说,如果我们使用的功能并不被我们选择的协议支持,那么JavaMailAPI并不可能如魔术师一样神奇的赋予我们这种能力。1.SMTP简单邮件传输协议定义了递送邮件的机制。在下文中,我们将使用基于Java-Mail的程序与公司或者ISP的SMTP服务器进行通讯。这个SMTP服务器将邮件转发到接收者的SMTP服务器,直至最后被接收者通过POP或者IMAP协议获取。这并不需要SMTP服务器使用支持授权的邮件转发,但是却的确要注意SMTP服务器的正确设置(SMTP服务器的设置与JavaMailAPI无关)。2.POPPOP是一种邮局协议,目前为第3个版本,即众所周知的POP3。POP定义了一种用户如何获得邮件的机制。它规定了每个用户使用一个单独的邮箱。大多数人在使用POP时所熟悉的功能并非都被支持,例如查看邮箱中的新邮件数量。而这个功能是微软的Outlook内建的,那么就说明微软Outlook之类的邮件客户端软件是通过查询最近收到的邮件来计算新邮件的数量来实现前面所说的功能。因此在我们使用JavaMailAPI时需要注意,当需要获得如前面所讲的新邮件数量之类的信息时,我们不得不自己进行计算。3.IMAPIMAP使用在接收信息的高级协议,目前版本为第4版,所以也被称为IMAP4。需要注意的是在使用IMAP时,邮件服务器必须支持该协议。从这个方面讲,我们并不能完全使用IMAP来替代POP,不能期待IMAP在任何地方都被支持。假如邮件服务器支持IMAP,那么我们的邮件程序将能够具有以下被IMAP所支持的特性:每个用户在服务器上可具有多个目录,这些目录能在多个用户之间共享。其与POP相比高级之处显而易见,但是在尝试采取IMAP时,我们认识到它并不是十分完美的:由于IMAP需要从其它服务器上接收新信息,将这些信息递送给用户,维护每个用户的多个目录,这都为邮件服务器带来了高负载。并且IMAP与POP的一个不同之处是POP用户在接收邮件时将从邮件服务器上下载邮件,而IMAP允许用户直接访问邮件目录,所以在邮件服务器进行备份作业时,由于每个长期使用此邮件系统的用户所用的邮件目录会占有很大的空间,这将直接导致邮件服务器上磁盘空间暴涨。4.MIMEMIME并不是用于传送邮件的协议,它作为多用途邮件的扩展定义了邮件内容的格式:信息格式、附件格式等等。一些RFC标准都涉及了MIME:RFC822,RFC2045,RFC2046,RFC2047,有兴趣的Matrixer可以阅读一下。而作为JavaMailAPI的开发者,我们并不需关心这些格式定义,但是这些格式被用在了程序中。5.NNTP和其它的第三方协议正因为JavaMailAPI在设计时考虑到与第三方协议实现提供商之间的分离,故我们可以很容易的添加一些第三方协议。SUN维护着一个第三方协议实现提供商的列表:,通过此列表我们可以找到所需要的而又不被SUN提供支持的第三方协议:比如NNTP这个新闻组协议和S/MIME这个安全的MIME协议。三、安装1.安装JavaMail为了使用JavaMailAPI,需要从下载文件名格式为javamail-[version].zip的文件(这个文件中包括了JavaMail实现),并将其中的mail.jar文件添加到CLASSPATH中。这个实现提供了对SMTP、IMAP4、POP3的支持。注意:在安装JavaMail实现之后,我们将在demo目录中发现许多有趣的简单实例程序。在安装了JavaMail之后,我们还需要安装JavaBeansActivationFramework,因为这个框架是JavaMailAPI所需要的。如果我们使用J2EE的话,那么我们并无需单独下载JavaMail,因为它存在于J2EE.jar中,只需将J2EE.jar加入到CLASSPATH即可。2.安装JavaBeansActivationFramework从下载JavaBeansActivationFramework,并将其添加到CLASSPATH中。此框架增加了对任何数据块的分类、以及对它们的处理的特性。这些特性是JavaMailAPI需要的。虽然听起来这些特性非常模糊,但是它对于我们的JavaMailAPI来说只是提供了基本的MIME类型支持。到此为止,我们应当把mail.jar和activation.jar都添加到了CLASSPATH中。当然如果从方便的角度讲,直接把这两个Jar文件复制到JRE目录的lib/ext目录中也可以。四、初次认识JavaMailAPI1.了解我们的JavaMail环境A.纵览JavaMail核心类结构打开JavaMail.jar文件,我们将发现在javax.mail的包下面存在着一些核心类:Session、Message、Address、Authenticator、Transport、Store、Folder。而且在javax.mail.internet包中还有一些常用的子类。B.SessionSession类定义了基本的邮件会话。就像Http会话那样,我们进行收发邮件的工作都是基于这个会话的。Session对象利用了java.util.Properties对象获得了邮件服务器、用户名、密码信息和整个应用程序都要使用到的共享信息。Session类的构造方法是私有的,所以我们可以使用Session类提供的getDefaultInstance()这个静态工厂方法获得一个默认的Session对象:Propertiesprops=newProperties();//fillpropswithanyinformationSessionsession=Session.getDefaultInstance(props,null);或者使用getInstance()这个静态工厂方法获得自定义的Session:Propertiesprops=newProperties();//fillpropswithanyinformationSessionsession=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(president@whitehouse.gov);如果要在邮件地址后面增加名字的话,可以通过传递两个参数:代表邮件地址和名字的字符串来建立一个具有邮件地址和名字的邮件地址类:Addressaddress=newInternetAddress(president@whitehouse.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