Java Mail API 是Sun开发的最新标准扩展API之一,它给Java应用程序开发者提供了独立于平台和协议的邮件/通讯解决方案。本文介绍该API的核心机制,并通过一个邮件转发服务器(邮件列表服务器)演示其具体用法。
Java Mail API的开发是Sun为Java开发者提供公用API框架的持续努力的良好例证。提倡公用框架,反对受限于供应商的解决方案,充分预示着一个日益开放的开发环境的建立。
在email通讯领域,面向最终应用的开发者(以及用户)已经能够购买到最适合他们需要的公用API框架实现,而低层开发者能够提供有效访问特定邮件服务的解决方案。其意义在于:小型开发组能够集中精力于开发高性能的客户端邮件软件,而为它提供不同邮件环境下的支持则变得相当容易;大型开发组织则侧重于为新开发的企业级邮件服务提供公用的访问支持,并由此获得丰富的应用软件支持。最大的赢家是信息系统用户,它能够按照要求(性能、投资等)方便地集成由不同厂商提供的产品和方案。 开发高度可重用的开放API框架的关键之一在于强调抽象接口技术,即在支持现有标准的基础上,支持未来扩展和可选实现。Java Mail API体现了这一思想。Sun和其它开发商正在为大多数现有的公用标准和协议提供缺省实现和工具。已经可用的支持至少包括:POP3、SMTP、IMAP等。
一、 Java Mail API 介绍
Java Mail API 的结构本身证明了它的开发者的基本目标之一——软件开发的工作量应该取决于应用程序本身的复杂程度以及开发者所要求的控制程度。换句话说,Java Mail API尽可能地保持简单。本文所附示例程序ListServer(以及API软件包所带的演示程序)充分说明了这一点。
乍看起来,Java Mail API所拥有的类总数以及类之间的关系可能让人误解为需要漫长的学习时间。实际上,一旦正式开始使用,你就会发现该API不失为在应用程序中加入健壮的邮件/通讯支持的简单工具。
Java Mail API包括的类数量远远大于此处涉及的类数量。下面按照在一个典型的应用程序中各个类出现过程为序,集中介绍部分核心类的功能和作用:
◆javax.mail.Session
javax.mail.Session是Java Mail API最高层入口类。它最常用的方法用于为不同邮件协议控制和装载SPI(即Service Provider Implementation)。如javax.mail.Store是通过Session类获得的。
◆javax.mail.Store
javax.mail.Store类实现特定邮件协议上的读、写、监视、查找等操作。通过javax.mail.Store类可以访问javax.mail.Folder类。
◆javax.mail.Transport
javax.mail.Transport类也是由服务提供者提供的类,实现用特定协议发送消息/邮件。
◆javax.mail.Folder
javax.mail.Folder类用于分级组织邮件,并提供按照javax.mail.Message格式访问email的能力。
◆javax.mail.Message
javax.mail.Message类模型化实际email消息的所有细节,如标题、发送/接收地址、发送日期等等。
◆Java Mail API 与 JAF
值得一提的是,Java Mail API实际上依赖于另外一个Java 扩展JAF,即JavaBean活动框架(JavaBean Activation Framework)。JAF的目的在于统一处理不同数据格式的方法(不管数据格式为简单文本还是由图片、声音、视频甚至其它“活动”内容共同组成的复合文档)。在这个意义上,JAF对Java的作用正如插件对Web浏览器的作用。
建立JavaMail使用环境,需要哪些软件
首先,需要安装JavaMail API。现在有两种常用的 JavaMail API 版本:1.2 和 1.1.3。虽然版本 1.2 是最新版,但版本 1.1.3 包含了Java 2 平台企业版(Java 2 Platform, Enterprise Edition,J2EE)的版本 1.2.1,所以仍然有很多人使用它。
·JavaMail 1.2 的安装
要使用 JavaMail 1.2 API,请下载 JavaMail 1.2 实现,解开Javamail-1_2.zip 文件,并将 mail.jar 文件添加到 CLASSPATH 中。除了核心类,随版本 1.2 实现一起提供的还有 SMTP、IMAP4 和 POP3 供应商。
· JavaMail 1.1.3 的安装
要使用 JavaMail 1.1.3 API,请下载 JavaMail 1.1.3 实现,解开Javamail1_1_3.zip文件,并将 mail.jar 文件添加到您的 CLASSPATH 中。除了核心类,随版本 1.1.3 实现一起提供的还有 SMTP 和 IMAP4 供应商。
如果您用 JavaMail 1.1.3 访问一个 POP 服务器,请下载并安装一个 POP3 供应商。Sun 就有一个独立于 JavaMail 实现。下载并解开 pop31_1_1.zip 文件后,将 pop3.jar 也添加到您的 CLASSPATH 中。
其次是JavaBeans Activation Framework 的安装。JavaMail API 的所有版本都需要 JavaBeans Activation Framework 来支持任意数据块的输入及相应处理。功能似乎不多,但目前许多浏览器和邮件工具中都能找到这种基本的 MIME 型支持。下载完框架后,解开 jaf1_0_1.zip 文件,并将 activation.jar 文件添加到 CLASSPATH 中。
对于 JavaMail 1.2 用户来说,现在您应该已将 mail.jar 和 activation.jar 文件添加到 CLASSPATH 中了。
而对于 JavaMail 1.1.3 用户,现在您应该已将 mail.jar、pop3.jar和 activation.jar文件添加到 CLASSPATH 中了。如果不打算用 POP3,就不必将 pop3.jar 添加到 CLASSPATH 中去。
如果您不想更改 CLASSPATH 环境变量,将 jar 文件复制到您 Java 运行时环境(Java Runtime Environment,JRE)目录下的 lib/ext 目录中去。例如,J2SE 1.3 发行版的缺省目录在 Windows 平台的 C:/jdk1.3/jre/lib/ext。
怎样样使用JSP发送email?
下面我们通过一个简单的例子,来说明在JSP中邮件是如何发送的。该例由两个文件组成。一个是HTML文件,用来建立邮件信息(包括发送人、接收人、主题等)的表单,并将表单内容发送给JSP文件;另外一个是JSP页面,负责邮件的发送。
HTML文件 <HTML> <BODY> <FORM action="sendmail.jsp" method="post"> <TABLE align="center"> <TR> <TD width="50%"> To:<BR><INPUT name="to" size="25"> </TD> <TD width="50%"> From:<BR><INPUT name="from" size="25"> </TD> </TR> <TR> <TD colspan="2"> Subject:<BR><INPUT name="subject" size="50"> </TD> </TR> <TR> <TD colspan="2"> <P>Message:<BR> <TEXTAREA name="text" rows=25 cols=85></TEXTAREA> </P> </TD> </TR> </TABLE> <INPUT type="submit" name="cb_submit" value=" Send "> <INPUT type="reset" name="cb_reset" value=" Clear "> </FORM> </BODY> </HTML> |
JSP页面的作用就是获得表单提交过来的数据,并将这些数据赋给Java Mail API中相应的对象,最后完成邮件发送。
sendmail.jsp文件 <%@ page import=" Javax.mail.*, Javax.mail.internet.*, Javax.activation.*,Java.util.*"%> <html> <head> <TITLE>JSP meets JavaMail, what a sweet combo.</TITLE> </head> <body> <% try{ Properties props = new Properties(); Session sendMailSession; Store store; Transport transport; sendMailSession = Session.getInstance(props, null); props.put("mail.smtp.host", "smtp.jspinsider.com"); Message newMessage = new MimeMessage(sendMailSession); newMessage.setFrom(new InternetAddress(request.getParameter("from"))); newMessage.setRecipient(Message.RecipientType.TO, new InternetAddress ( request.getParameter ("to"))); newMessage.setSubject(request.getParameter("subject")); newMessage.setSentDate(new Date()); newMessage.setText(request.getParameter("text")); transport = sendMailSession.getTransport("smtp"); transport.send(newMessage); %> <P>Your mail has been sent.</P> <% }catch(MessagingException m) { out.println(m.toString()); } %> </body> </html> |
如何发送HTML类型的邮件
在上面的例子中,我们实现了如何发送文本格式的邮件,那么HTML格式的邮件该如何发送呢?那就看看下面的例子吧。
该例由四个文件组成:
·form.htm:用来建立邮件信息的表单
·send.jsp:用来获取表单提交的信息,并调用mymail.mail.HTML.send()方法发送邮件
·StringDataSource.Java:用户自定义的JavaBean,用来将邮件的Body部分转化为HTML格式
·HTML.Java:用户自定义的JavaBean,用来发送HTML格式的邮件。在send.jsp文件中提到的mymail.mail.HTML.send()方法就在该JavaBean中定义。
form.htm <html> <head> <meta http-equiv="Content-Type" content="text/html; charset=gb2312"> <title> JavaMail - 发送HTML邮件</title> </head> <body> <table border="0" cellspacing="0" cellpadding="0"> <form method="post" action="send.jsp"> <tr> <td>SMTP主机:</td> <td><input type="text" name="smtp" size="80"></td> </tr> <tr> <td>发信人:</td> <td><input type="text" name="from" size="80"></td> </tr> <tr> <td>收信人:</td> <td><input type="text" name="to" size="80"></td> </tr> <tr> <td>抄送人:</td> <td><input type="text" name="cc" size="80"></td> </tr> <tr> <td>暗送人:</td> <td><input type="text" name="bcc" size="80"></td> </tr> <tr> <td>主题:</td> <td><input type="text" name="subject" size="80"></td> </tr> <tr> <td valign="top">内容:</td> <td><textarea name="body" rows="5" cols="80"></textarea></td> </tr> <tr> <td colspan="2" align="center"><input type="submit" value="发送"></td> </tr> </form> </table> </body> </html> send.jsp <% //变量声明 Java.lang.String smtp,from,to,cc,bcc,subject,body; //获得用户输入数据 smtp = request.getParameter("smtp"); from = request.getParameter("from"); to = request.getParameter("to"); cc = request.getParameter("cc"); bcc = request.getParameter("bcc"); subject = request.getParameter("subject"); if(subject!=null){ subject = new Java.lang.String(subject.getBytes("iso-8859-1")); } body = request.getParameter("body"); //发送邮件 mymail.mail.HTML.send(smtp,from,to,cc,bcc,subject,body); %> mymail.jaf.StringDataSource.Java package mymail.jaf; public class StringDataSource implements Javax.activation.DataSource { private Java.lang.String data; private Java.lang.String type; public StringDataSource(Java.lang.String data,Java.lang.String type){ this.data = data; this.type = type; } public Java.io.InputStream getInputStream() throws Java.io.IOException{ return new Java.io.StringBufferInputStream(data); } public Java.io.OutputStream getOutputStream() throws Java.io.IOException{ throw new Java.io.IOException("it does not support this method now!"); } public Java.lang.String getContentType(){ return type; } public Java.lang.String getName(){ return " mymail "; } } mymail.mail.HTML.Java package mymail.mail; public final class HTML { public static void send( Java.lang.String smtp, /*SMTP主机地址*/ Java.lang.String from, /*发信人*/ Java.lang.String to, /*收信人*/ Java.lang.String cc, /*抄送人*/ Java.lang.String bcc, /*暗送人*/ Java.lang.String subject, /*主题*/ Java.lang.String body /*内容*/ ) throws Java.lang.Exception { //变量声明 Java.util.Properties props; //系统属性 Javax.mail.Session mailSession; //邮件会话对象 Javax.mail.internet.MimeMessage mimeMsg; //MIME邮件对象 //设置系统属性 props = Java.lang.System.getProperties(); //获得系统属性对象 props.put("mail.smtp.host",smtp); //设置SMTP主机 //获得邮件会话对象 mailSession = Javax.mail.Session.getDefaultInstance(props,null); //创建MIME邮件对象 mimeMsg = new Javax.mail.internet.MimeMessage(mailSession); //设置发信人 mimeMsg.setFrom(new Javax.mail.internet.InternetAddress(from)); //设置收信人 if(to!=null) { mimeMsg.setRecipients(Javax.mail.Message.RecipientType.TO,Javax.mail. internet.InternetAddress.parse(to)); } //设置抄送人 if(cc!=null) { mimeMsg.setRecipients(Javax.mail.Message.RecipientType.CC,Javax.mail. internet.InternetAddress.parse(cc)); } //设置暗送人 if(bcc!=null) { mimeMsg.setRecipients(Javax.mail.Message.RecipientType.BCC,Javax.mail. internet.InternetAddress.parse(bcc)); } //设置邮件主题 //mimeMsg.setSubject(subject); mimeMsg.setSubject(subject,"gb2312"); //设置邮件内容,将邮件body部分转化为HTML格式 mimeMsg.setDataHandler(new Javax.activation.DataHandler(new mymail.jaf. StringDataSource (body,"text/html"))); //发送邮件 Javax.mail.Transport.send(mimeMsg); } } |
如何实现消息和标志的删除?
消息的删除涉及到与消息相关的 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 提出请求。
要删除消息,您可以设置消息的 DELETED flag:
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 提示用户输入用户名和密码,而不是将用户名和密码作为字符串传递。在这里您会明确了解怎样更充分的使用Java Mail API的认证机制。
不用主机、用户名和密码与 Store 相连接,而是设置 Properties 来拥有主机,然后告诉 Session 自定义的 Authenticator 实例,如下所示:
// Setup properties Properties props = System.getProperties(); props.put("mail.pop3.host", host); // Setup authentication, get session Authenticator auth = new PopupAuthenticator(); Session session = Session.getDefaultInstance(props, auth); // Get the store Store store = session.getStore("pop3"); store.connect(); |
然后,创建一个 Authenticator 子类并从 getPasswordAuthentication() 方法中返回 PasswordAuthentication 对象。下面就是这样一种实现,其中用户名和密码仅占用一个域。(这不是一个 Swing 工程教程;只要将两部分输入同一个域,用逗号分隔就行。)
import Javax.mail.*; import Javax.swing.*; import Java.util.*; public class PopupAuthenticator extends Authenticator { public PasswordAuthentication getPasswordAuthentication() { String username, password; String result = JOptionPane.showInputDialog("Enter 'username,password'"); StringTokenizer st = new StringTokenizer(result, ","); username = st.nextToken(); password = st.nextToken(); return new PasswordAuthentication(username, password); } } |
因为 PopupAuthenticator 涉及到 Swing,它会启动 AWT 的事件处理线程。这一点基本上要求您在代码中添加一个对 System.exit() 的调用来终止程序。
如何实现消息的转发?
转发消息,相对于其他功能来说,显得有些棘手。没有单独的方法可以供调用,读者必须通过对组成消息各部分的处理来组织要转发的消息。
一条邮件消息可以由多个部分组成。在处理 MIME 消息时,消息中每部分都是 BodyPart,再特殊些,是 MimeBodyPart。不同的 body part(信体部件或正文部件)结合成一个容器,名为 Multipart,再特殊些,就是 MimeMultipart。要转发一条消息,您为自己的消息正文创建一个部件,要转发的消息作为另一部件。并且将两个部件结合成一个 multipart(多部件)。然后您将这个 multipart 添加到一则已写好恰当地址的消息中,并发送。
本质上就是如此。要将一条消息内容复制到另一条,只要复制 DataHandler (JavaBeans Activation Framework 中的类)就行了。
// Create the message to forward Message forward = new MimeMessage(session); // Fill in header forward.setSubject("Fwd: " + message.getSubject()); forward.setFrom(new InternetAddress(from)); forward.addRecipient(Message.RecipientType.TO, new InternetAddress(to)); // Create your new message part BodyPart messageBodyPart = new MimeBodyPart(); messageBodyPart.setText( "Here you go with the original message:/n/n"); // Create a multi-part to combine the parts Multipart multipart = new MimeMultipart(); multipart.addBodyPart(messageBodyPart); // Create and fill part for the forwarded content messageBodyPart = new MimeBodyPart(); messageBodyPart.setDataHandler(message.getDataHandler()); // Add part to multi part multipart.addBodyPart(messageBodyPart); // Associate multi-part with message forward.setContent(multipart); // Send message Transport.send(forward); |
怎样处理附件?
附件是邮件消息的相关资源,如通常不包含在消息正文里文本文件、电子表格或图像等。常见的邮件程序,如 Eudora 和 pine 之类,可以用 JavaMail API 将资源 attach(附加) 到您的消息上,就可以在收到消息时得到。
附件的发送:
发送附件非常像转发消息。您建立各部分以组成完整消息。完成第一部件,即消息正文后,您添加其它部件,其中每个 DataHandler 都代表附件,而不是转发消息情况下的共享处理程序。如果从文件中读附件,附件的数据源是 FileDataSource。而如果从 URL 中读时,附件的数据源是 URLDataSource。一旦存在 DataSource,只要先把它传递给 DataHandler 构造器,最后再用 setDataHandler() 把它附加到 BodyPart。假定您要保留附件的原始文件名,最终要做的是用 BodyPart 的 setFileName() 方法设置与附件相关的文件名。如下所示:
// Define message Message message = new MimeMessage(session); message.setFrom(new InternetAddress(from)); message.addRecipient(Message.RecipientType.TO, new InternetAddress(to)); message.setSubject("Hello JavaMail Attachment"); // Create the message part BodyPart messageBodyPart = new MimeBodyPart(); // Fill the message messageBodyPart.setText("Pardon Ideas"); Multipart multipart = new MimeMultipart(); multipart.addBodyPart(messageBodyPart); // Part two is attachment messageBodyPart = new MimeBodyPart(); DataSource source = new FileDataSource(filename); messageBodyPart.setDataHandler(new DataHandler(source)); messageBodyPart.setFileName(filename); multipart.addBodyPart(messageBodyPart); // Put parts in message message.setContent(multipart); // Send the message Transport.send(message); |
就消息引入附件时,若程序是个 servlet (小服务程序),除告知消息发送到何处外,还必需上载附件。可以将 multipart/form-data 表单编码类型(form encoding type)用于每个上载文件的处理。
<FORM ENCTYPE="multipart/form-data" method=post action="/myservlet"> <INPUT TYPE="file" NAME="thefile"> <INPUT TYPE="submit" VALUE="Upload"> </FORM> |
注意:消息大小由 SMTP 服务器而不是 JavaMail API 来限制。如果您碰到问题,可以考虑用设置 ms 和 mx 参数的方法增大 Java 堆大小。
附件的获取:
从消息中获取附件比发送它们棘手些,因为 MIME 没有简单的关于附件的概念。当消息包含附件时,消息的内容是个 Multipart 对象。接着,您需要处理每个 Part,获取主要内容和附件。标有从 part.getDisposition() 获得的 Part.ATTACHMENT 配置(disposition)的部件(Part)无疑就是附件。但是,没有配置(以及一个非文本 MIME 类型)和带 Part.INLINE 配置的部件也可能是附件。当配置要么是 Part.ATTACHMENT,要么是 Part.INLINE 时,这个消息部件的内容就能被保存。只要用 getFileName() 和 getInputStream() 就能分别得到原始文件名和输入流。
Multipart mp = (Multipart)message.getContent(); for (int i=0, n=multipart.getCount(); i<n; i++) { Part part = multipart.getBodyPart(i)); String disposition = part.getDisposition(); if ((disposition != null) && ((disposition.equals(Part.ATTACHMENT) || (disposition.equals(Part.INLINE))) { saveFile(part.getFileName(), part.getInputStream()); } } |
saveFile() 方法仅依据文件名创建了一个 File,它从输入流中将字节读出,然后写入到文件中。万一文件已经存在,就在文件名后添加一个数字作为新文件名,如果这个文件名仍存在,则继续添,直到找不到这样的文件名为止。
// from saveFile() File file = new File(filename); for (int i=0; file.exists(); i++) { file = new File(filename+i); } |
上面的代码涵盖了最简单的情况 - 消息中各部件恰当的标记了。要涵盖所有情况,还要在配置为空时进行处理,并且获取部件的 MIME 类型来进行相应处理。
if (disposition == null) { // Check if plain MimeBodyPart mbp = (MimeBodyPart)part; if (mbp.isMimeType("text/plain")) { // Handle plain } else { // Special non-attachment cases here of image/gif, text/html, ... } ... } |
如何一次发送多个邮件?
取得必要的Transport对象并调用SendMessage()发送每一个邮件。注意在调用之间设置或改变接收者。
Message message = …; Transport t = session.getTransport("smtp"); t.connect(); message.setRecipient(Message.RecipientType.TO,recipient1); t.sendMessage(message,recipient); message.setRecipient(Message.RecipientType.TO,recipient2); t.sendMessage(message,recipient); message.setRecipient(Message.RecipientType.TO,recipient3); t.sendMessage(message,recipient); t.close(); |
如何保存邮件?
用MimeMessage类的writeTo()方法可以实现。用Message类的对象不能实现。
FileOutputStream fos = new FileOutputStream("test.mail"); Mimemessage.writeTo(fos); |
怎样发送带有图像的HTML格式邮件?
一些图像还是放在服务器上较好,让用户的邮件工具处理。读者可以将图像作为附件或HTML体发送。如果所有附件保存在同一个目录下,那么必须用不同的图像文件名以确保邮件工具不会显示其他图片。另外图像URL要用绝对路径,不能用相对路径。
如何设置∕获取邮件的优先级?
设置邮件的优先级,只需在消息头中添加"X-Priority"属性:
MimeMessage msg;
Msg.addHeader("X-Priority","1");
同样道理,要获取邮件的优先级只要获取"X-Priority"属性的值就可以了:
String priority = msg.getHeader("X-Priority");
附录:Java Mail API的基本概念
什么是Java Mail API
JavaMail API 是一个用于阅读、编写和发送电子邮件的可选包(标准扩展)。与 Eudora、pine 及 Microsoft Outlook 相似,这个包用来创建邮件用户代理(Mail User Agent,MUA) 类型程序。API 的主要用途并不在于传输、发送和转发消息;这一功能范围属于某些应用程序,如 sendmail 及其它邮件传输代理(Mail Transfer Agent,MTA)类型程序。MUA 类型的程序能让用户阅读和书写邮件,而它却依赖 MTA 处理实际发送。
什么是SMTP
SMTP(Simple Mail Transfer Protocol),即简单邮件传输协议,它定义了发送电子邮件的机制。在 JavaMail API 环境中,基于 JavaMail 的程序将和您的公司或因特网服务供应商的(Internet Service Provider's,ISP's)SMTP 服务器通信。SMTP 服务器可将消息中转至接收方 SMTP 服务器,以便最终让用户经由 POP 或 IMAP 获得。这不是要求 SMTP 服务器成为开放的中继,尽管 SMTP 服务器支持身份验证,不过还是得确保它的配置正确。像配置服务器来中继消息或添加删除邮件账号这类任务的实现,JavaMail API 中并不支持。
什么是POP
POP(Post Office Protocol),即邮局协议。目前用的是版本3,所以人们通常将它称为 POP3,RFC 1939 定义了这个协议。POP 和SMTP一样,也是一种机制,Internet上大多数人通过它得到邮件。该协议规定每个用户只能有一个邮箱的支持。这就是它所能做的,而这也造成了许多混淆。使用 POP 时,用户熟悉的许多性能并不是由 POP 协议支持的,如查看有几封新邮件消息这一性能。这些性能内建于如 Eudora 或 Microsoft Outlook 之类的程序中,它们能记住一些事,诸如最近一次收到的邮件,还能计算出有多少是新的。所以当使用 JavaMail API 时,如果读者想要这类信息,就只能由自己来计算了。
什么是IMAP
IMAP(Internet Message Access Protocol),即Internet消息访问协议,是更高级的用于接收消息的协议,在 RFC 2060 中有它的定义。目前使用的IMAP版本为4,人们习惯将它称为 IMAP4。在用到 IMAP 时,邮件服务器必需支持这个协议。不能仅仅把使用 POP 的程序用于 IMAP,并指望它支持 IMAP 所有性能。假设邮件服务器支持 IMAP,基于 JavaMail 的程序可以利用这种情况--用户在服务器上可以有多个文件夹(folder),并且这些文件夹可以被多个用户共享。
因为有这一更高级的性能,您也许会认为所有用户都会使用 IMAP。事实并不是这样。要求服务器接收新消息,在用户请求时发送到用户手中,还要在每个用户的多个文件夹中维护消息。这样虽然能将消息集中备份,但随着用户长期的邮件夹越来越大,到磁盘空间耗尽时,每个用户都会受到损失。使用 POP,就能卸载邮件服务器上保存的消息了。
什么是MIME
MIME(Multipurpose Internet Mail Extensions),即多用途Internet邮件扩展标准。它不是邮件传输协议,而是对传输内容的消息、附件及其它的内容定义了格式。这里有很多不同的RFC(Requirement of Comment)文档:RFC 822、RFC 2045、RFC 2046 和 RFC 2047。作为一个 JavaMail API 的用户,您通常不必对这些格式操心。无论如何,一定存在这些格式而且程序会用到它。