第14章通过JavaMailAPI收发邮件参考《Java网络编程精解》的第14章14.1E-mail协议简介14.2JavaMailAPI简介14.3建立JavaMail应用程序的开发环境14.4创建JavaMail应用程序14.5身份验证14.6URLName类14.7创建和读取复杂电子邮件14.8操纵邮件夹14.1E-mail协议简介邮件服务器按照提供的服务类型,可以分为发送邮件服务器(简称发送服务器)和接收邮件服务器(简称接收服务器)。发送邮件服务器使用邮件发送协议,现在常用的是SMTP,所以通常发送邮件服务器也称为SMTP服务器;接收邮件服务器使用接收邮件协议,常用的有POP3协议和IMAP协议,所以通常接收邮件服务器也称为POP3服务器或IMAP服务器。14.1E-mail协议简介14.1.1SMTP简单邮件传输协议SMTP(SimpleMailTransferProtocol),即简单邮件传输协议,是Internet传送E-mail的基本协议,也是TCP/IP协议组的成员。SMTP协议解决邮件系统如何通过一条链路,把邮件从一台机器传送到另一台机器上的问题。SMTP协议的特点是具有良好的可伸缩性,这也是它成功的关键。它既适用于广域网,也适用于局域网。SMTP协议由于非常简单,使得它得到了广泛的运用,在Internet上能够发送邮件的服务器几乎都支持SMTP协议。14.1.2POP3邮局协议POP3(PostOfficeProtocol3),即邮局协议第3版,是Internet接收邮件的基本协议,也是TCP/IP协议组的成员。RFC1939描述了POP3协议,网址为“”。POP3既允许接收服务器向邮件用户发送邮件,也可以接收来自SMTP服务器的邮件。邮件客户端软件会与POP3服务器交互,下载由POP3服务器接收到的邮件。基于POP3协议的邮件系统能提供快速、经济和方便的邮件接收服务,深受用户的青睐。14.1.3接收邮件的新协议IMAPIMAP(InternetMessageAccessProtocol),即互联网消息访问协议,是一种功能比POP3更强大的新的接收邮件协议。目前最新的IMAP协议版本为IMAP4,RFC2060描述了IMAP4,网址为“”。IMAP4与POP3协议一样提供了方便的下载邮件服务,允许用户在脱机状态下阅读已经下载到本地硬盘的邮件。但IMAP4的功能远远不只这些,它还具有以下功能:摘要浏览邮件的功能。选择性下载附件的功能。鼓励用户把邮件一直存储在邮件服务器上。允许用户把远程邮件服务器上的邮箱作为信息存储工具。14.1.4MIME简介MIME(MultipurposeInternetMailExtensions,多用途Internet邮件扩充标准)不是邮件传输协议,而是对邮件格式所作的规范。RFC2045、RFC2046和RFC2047对MIME作了描述。MIME是对RFC822的扩充,RFC822规定了内容只包括采用ASCII编码的纯文本的邮件的格式,而MIME允许在邮件中包含附件。14.2JavaMailAPI简介SUN公司制定了JavaMailAPI,它封装了按照各种邮件通信协议,如IMAP、POP3和SMTP,与邮件服务器通信的细节,为Java应用程序提供了收发电子邮件的公共接口,参见图14-2。14.2JavaMailAPI简介JavaMailAPI主要位于javax.mail包和javax.mail.internet中,图14-3为其中主要类的类框图。14.2JavaMailAPI简介1.javax.mail.Session类:表示邮件会话,是JavaMailAPI的最高层入口类。2.javax.mail.Store类:表示接收邮件服务器上的注册用户的存储空间,通过Store类的getFolder()方法,可以访问用户的特定邮件夹。3.javax.mail.Folder类:代表邮件夹。4.javax.mail.Message类:代表电子邮件。5.javax.mail.Address类:代表邮件地址。6.javax.mail.Transport类:根据指定的邮件发送协议(通常是SMTP),通过指定的邮件发送服务器来发送邮件。14.3建立JavaMail应用程序的开发环境JDK中并不包含JavaMailAPI。为了开发JavaMail应用程序,需要从SUN公司的网站下载JavaMailAPI及其实现的类库,该类库由两个JAR文件组成:mail.jar和activation.jar。另外,为了运行本课介绍的程序,还应该准备好可以访问的邮件服务器。本课选用Merak邮件服务器,它是一个商业邮件服务器,支持STMP、POP3和IMAP协议。可以从网站上下载它的试用版本。14.4创建JavaMail应用程序假定邮件服务器安装在本地计算机上,客户程序访问邮件服务器的admin@mydomain.com用户需要提供如下信息:Stringhostname=localhost;Stringusername=admin;Stringpassword=1234;14.4创建JavaMail应用程序JavaMail应用程序在初始化过程中需要执行如下步骤。步骤(1)设置JavaMail属性:Propertiesprops=newProperties();props.put(mail.transport.protocol,smtp);props.put(mail.store.protocol,imap);props.put(mail.smtp.class,com.sun.mail.smtp.SMTPTransport);props.put(mail.imap.class,com.sun.mail.imap.IMAPStore);props.put(mail.smtp.host,hostname);14.4创建JavaMail应用程序以上代码设置了如下JavaMail属性:mail.transport.protocol:指定邮件发送协议。mail.store.protocol:指定邮件接收协议。mail.smtp.class:指定支持SMTP协议的Transport具体类,允许由第三方提供。mail.imap.class:指定支持IMAP协议的Store具体类,允许由第三方提供。mail.smtp.host:指定采用SMTP协议的邮件发送服务器的IP地址或主机名。14.4创建JavaMail应用程序步骤(2)调用javax.mail.Session类的静态方法Session.getDefaultInstance()获得Session实例,该方法根据已经配置的JavaMail属性来创建Session实例:Sessionmailsession=Session.getDefaultInstance(props);步骤(3)调用Session的getStore(Stringprotocol)方法来获得Store对象,参数protocol指定接收邮件协议:Storestore=mailsession.getStore(imap);步骤(1)把mail.imap.class属性设为com.sun.mail.imap.IMAPStore,因此以上getStore()方法返回com.sun.mail.imap.IMAPStore类的实例。14.4创建JavaMail应用程序步骤(4)调用Store对象的connect()方法连接到接收邮件服务器。调用connect()方法时,应该指定接收邮件服务器的主机名或IP地址、用户名和口令。store.connect(hostname,username,password);14.4创建JavaMail应用程序获得了Store对象后,就可以通过它来访问邮件服务器上的特定邮件用户了。通常会对邮件用户执行以下操作。操作(1)创建并发送邮件://创建邮件msg=newMimeMessage(mailsession);InternetAddress[]toAddrs=InternetAddress.parse(admin@mydomain.com,false);//设置邮件接收者msg.setRecipients(Message.RecipientType.TO,toAddrs);//设置邮件的主题msg.setSubject(hello);//设置邮件的发送者msg.setFrom(newInternetAddress(admin@mydomain.com));//设置邮件的正文msg.setText(Howareyou);//发送邮件Transport.send(msg);Transport的静态方法send(Message)负责发送邮件服务器,邮件发送协议由mail.transport.protocol属性指定,邮件发送服务器由mail.smtp.host属性指定。14.4创建JavaMail应用程序操作(2)打开inbox邮件夹收取邮件://获得名为“inbox”的邮件夹Folderfolder=store.getFolder(inbox);//打开邮件夹folder.open(Folder.READ_ONLY);//获得邮件夹中的邮件数目System.out.println(Youhave+folder.getMessageCount()+messagesininbox.);//获得邮件夹中的未读邮件数目System.out.println(Youhave+folder.getUnreadMessageCount()+unreadmessagesininbox.);在IMAP协议中,inbox邮件夹是邮件用户的保留邮件夹,用户不允许删除该邮件夹,邮件服务器把所有接收到的新邮件都存在该邮件夹中。14.4创建JavaMail应用程序操作(3)从邮件夹中读取邮件://从邮件夹中读取第一封邮件Messagemsg=folder.getMessage(1);System.out.println(------thefirstmessageininbox-------);//获得邮件的发送者、主题和正文System.out.println(From:+msg.getFrom()[0]);System.out.println(Subject:+msg.getSubject());System.out.println(Text:+msg.getText());14.5身份验证在实际应用中,往往希望在连接邮件服务器时,弹出一个对话框,提示用户输入用户名和口令。为了达到这一效果,需要按照以下步骤创建和使用javax.mail.Authenticator类:(1)创建一个javax.mail.Authenticator类的子类(假定名为MailAuthenticator),实现getPasswordAuthentication()方法。(2)创建MailAuthenticator对象,并且把它作为参数传给Session的getDefaultInstance()方法:Authenticatorma=newMailAuthenticator();Sessionsession=Session.getDefaultInstance(props,ma);(3)连接到接收邮件服务器时,把用户名和口令设为null:store.connect(receiveHost,null,null);14.5身份验证14.6URLName类javax.mail.URLName类表示URL的名字,URLName类与java.n