﻿<?xml version="1.0" encoding="utf-8" standalone="yes"?><rss version="2.0" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:trackback="http://madskills.com/public/xml/rss/module/trackback/" xmlns:wfw="http://wellformedweb.org/CommentAPI/" xmlns:slash="http://purl.org/rss/1.0/modules/slash/"><channel><title>BlogJava-JAVA涂鸦-文章分类-JavaMail</title><link>http://www.blogjava.net/rickhunter/category/6376.html</link><description>关于JAVA的点点滴滴</description><language>zh-cn</language><lastBuildDate>Tue, 27 Feb 2007 20:23:49 GMT</lastBuildDate><pubDate>Tue, 27 Feb 2007 20:23:49 GMT</pubDate><ttl>60</ttl><item><title>JavaMail简易教程</title><link>http://www.blogjava.net/rickhunter/articles/25616.html</link><dc:creator>千山鸟飞绝</dc:creator><author>千山鸟飞绝</author><pubDate>Tue, 27 Dec 2005 10:49:00 GMT</pubDate><guid>http://www.blogjava.net/rickhunter/articles/25616.html</guid><wfw:comment>http://www.blogjava.net/rickhunter/comments/25616.html</wfw:comment><comments>http://www.blogjava.net/rickhunter/articles/25616.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/rickhunter/comments/commentRss/25616.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/rickhunter/services/trackbacks/25616.html</trackback:ping><description><![CDATA[



<p>声明，本文转载自 <span lang="EN-US"><a href="http://dev.csdn.net/user/narilee">narilee</a>
</span>的<span lang="EN-US"> Blog<br>
<br>
JavaMail API</span>简介<span lang="EN-US"><br>
JavaMail API</span>是一种可选的、能用于读取、编写和发送电子消息的包（标准扩展）。您可使用这种包创建邮件用户代理（<span lang="EN-US">Mail User Agent </span>，<span lang="EN-US">MUA</span>） 类型的程序，它类似于<span lang="EN-US">Eudora</span>、<span lang="EN-US">Pine</span>及<span lang="EN-US">Microsoft
Outlook</span>这些邮件程序。其主要目的不是像发送邮件或其他邮件传输代理（<span lang="EN-US">Mail Transfer Agent</span>，<span lang="EN-US">MTA</span>）类型的程序那样用于传输、发送和转发消息。换句话说，用户可以与<span lang="EN-US">MUA</span>类型的程序交互，以阅读和撰写电子邮件。<span lang="EN-US">MUA</span>依靠<span lang="EN-US">MTA</span>处理 实际的发送任务。<span lang="EN-US"><br>
JavaMail API</span>的设计是，为收发信息提供与协议无关的访问。方式是把该<span lang="EN-US">API</span>划分成两个部分：<span lang="EN-US"><br>
· </span>该<span lang="EN-US">API</span>的第一个部分是本课程的重点。基本上是如何发送和接收独立于提供程序<span lang="EN-US">/</span>协议的消息。<span lang="EN-US"><br>
· </span>第二个部分则使用特定的协议语言，如：<span lang="EN-US">SMTP</span>、<span lang="EN-US">POP</span>、<span lang="EN-US">IMAP</span>和<span lang="EN-US">NNTP</span>。如果要让<span lang="EN-US">JavaMail
API</span>与服务器通信，就需要为之提供协议。由于<span lang="EN-US">Sun</span>公司对特定协议提供程序有充分的介绍，用户可以免费获取，所以本课程没有介绍创建特定协议提供程序的内容。<span lang="EN-US"><br>
</span>复习相关协议<span lang="EN-US"><br>
</span>在学习<span lang="EN-US">JavaMail API</span>的深层知识之前，让我们回过头来看一看在该<span lang="EN-US">API</span>中使用的协议<span lang="EN-US">,</span>本质上有<span lang="EN-US">4</span>种人们常用的协议：<span lang="EN-US"><br>
· SMTP<br>
· POP<br>
· IMAP<br>
· MIME<br style="">
<!--[if !supportLineBreakNewLine]--><br style="">
<!--[endif]--></span></p>

<p><a name="more"></a>您 还需要了解<span lang="EN-US">NNTP</span>及其他一些协议。理解这些协议的基本原理有助于您理解如何使用<span lang="EN-US">JavaMail API</span>。而该<span lang="EN-US">API</span>的设计要与协议无关，所以不能克服这些基础协议的限制。如果选用的协议不支持某种功能，那么<span lang="EN-US">JavaMail API</span>也无法在其上添加这种功能。（正如您一会儿就会看到的，在操作<span lang="EN-US">POP</span>协议时，常常会碰到这种问题）。<span lang="EN-US"><br>
SMTP<br>
</span>简单邮件传输协议 （<span lang="EN-US">SMTP</span>）是用于传送电子邮件的机制。在<span lang="EN-US">JavaMail
API</span>环境中，您的基于<span lang="EN-US">JavaMail</span>的程序将与您公司或<span lang="EN-US">Internet</span>服务提供商（<span lang="EN-US">ISP</span>）的<span lang="EN-US">SMTP</span>服务器通信。该<span lang="EN-US">SMTP</span>服务器将会把消息转发
给用作接收消息的<span lang="EN-US">SMTP</span>服务器，最后用户可通过<span lang="EN-US">POP</span>或<span lang="EN-US">IMAP</span>协议获取该消息。由于支持身份验证，所以不需要<span lang="EN-US">SMTP</span>服务器是一种开放的转发器，但需
要确保<span lang="EN-US">SMTP</span>服务器配置正确。<span lang="EN-US">JavaMail API</span>中没有集成用于处理诸如配置服务器以转发消息或添加<span lang="EN-US">/</span>删除电子邮件帐户这一类任务的功能。<span lang="EN-US"><br>
POP<br>
POP </span>的含义是邮局协议，当前的版本为<span lang="EN-US">3</span>，也称作<span lang="EN-US">POP3</span>，该协议是在<span lang="EN-US">RFC 1939</span>中定义的。<span lang="EN-US">POP</span>是<span lang="EN-US">Internet</span>上的大多数人用来接收邮件的机制。它为每个用户的每个邮箱定义支持，这是它所做的全部工作，也是大多数问题的
根源。在使用<span lang="EN-US">POP</span>协议时，人们熟悉的很多功能，如查看收到了多少新邮件消息的功能，<span lang="EN-US">POP</span>根本不支持。这些功能都内置到诸如<span lang="EN-US">Eudora</span>或<span lang="EN-US"> Microsoft Outlook</span>之类的邮件程序中，能为您记住接收的上一封邮件，以及计算有多少新邮件这类信息。因此，使用<span lang="EN-US">JavaMail API</span>时，如果想获取这类信息，将需要由自己进行计算。<span lang="EN-US"><br>
IMAP<br>
IMAP</span>是用于接收消息的更加高级的协议，它是在<span lang="EN-US">RFC 2060</span>中定义的。<span lang="EN-US">IMAP</span>的含义是<span lang="EN-US">“Internet</span>消息访问协议<span lang="EN-US">”</span>，当前版本是第<span lang="EN-US">4</span>版，也称作<span lang="EN-US">IMAP4</span>。使用<span lang="EN-US">IMAP</span>时，您的邮件服务器必须支持该 协议。您不能只是简单地把程序转变为支持<span lang="EN-US">IMAP</span>，而不是支持<span lang="EN-US">POP</span>，就指望能支持<span lang="EN-US">IMAP</span>中的一切。假定您的邮件服务器支持<span lang="EN-US">IMAP</span>，那么基于<span lang="EN-US"> JavaMail</span>的程序就可利用在服务器上拥有多个文件夹的用户，并且这些文件夹可以被多个用户共享的功能。<span lang="EN-US"><br>
</span>由于<span lang="EN-US">IMAP</span>协议具有更高级的功能， 您也许会想<span lang="EN-US">IMAP</span>应该被每一个人使用，但事实不是这样。因为<span lang="EN-US">IMAP</span>会加重邮件服务器的负荷，它需要服务器接收新消息，发送消息给请求的用户，并在多个 文件夹中为每个用户维护这些消息。而这要集中备份，因而长期下去用户的文件夹会变得越来越大，当磁盘空间用光了时，每个人都会遭受损失。而使用<span lang="EN-US">POP</span>协议 时，已保存消息可以解除服务器的重负。<span lang="EN-US"><br>
MIME<br>
MIME</span>的含义是<span lang="EN-US">“</span>多用途的网际邮件扩充协议<span lang="EN-US">”</span>。它不是一种邮件传输协议，相反，它定义传
输的内容：消息的格式、附件等。许多文档都定义了<span lang="EN-US">MIME</span>协议，包含：<span lang="EN-US">RFC
822</span>、<span lang="EN-US">RFC 2045</span>、<span lang="EN-US">RFC 2046</span>和<span lang="EN-US">RFC 2047</span>。作为<span lang="EN-US">JavaMail API</span>的用户，一般不需要担心这些格式。但是，这些格式确实存在，并为您的程序所用。<span lang="EN-US"><br>
NNP</span>和其他协议<span lang="EN-US"><br>
</span>由 于<span lang="EN-US">JavaMail API</span>分开了提供程序和其他部分，所以您可以轻松地为附加协议添加支持。<span lang="EN-US">Sun</span>公司提供第<span lang="EN-US">3</span>方提供程序清单，这些提供程序要利用<span lang="EN-US"> Sun</span>公司不支持的少见的协议。在这份清单中，您将会看到对<span lang="EN-US">NNTP</span>（网络新闻传输协议）<span lang="EN-US">[</span>新闻组<span lang="EN-US">]</span>、<span lang="EN-US">S/MIME</span>（安全多用途的网际邮件扩充协议）及其
他协议的提供支持的第<span lang="EN-US">3</span>方提供程序。<span lang="EN-US"><br>
</span>安装<span lang="EN-US"><br>
</span>目前有两种版本的<span lang="EN-US">JavaMail API</span>最常用：<span lang="EN-US">1.2</span>和<st1:chsdate year="1899" month="12" day="30" islunardate="False" isrocdate="False" w:st="on"><span lang="EN-US">1.1.3</span></st1:chsdate>。本课程中的所有例子都适用于这两种版本。其中<span lang="EN-US">JavaMail
API 1.2</span>是最新的，而<span lang="EN-US">JavaMail API 1.1.3</span>中包含了<span lang="EN-US">Java 2</span>企业版（<span lang="EN-US">J2EE</span>）平台<span lang="EN-US">1.2.1</span>版，所以它仍然很常用。使用<span lang="EN-US">JavaMail API</span>的版本会对您的下载和安装产生一些影响。这两种版本的<span lang="EN-US">JavaMail
API</span>都能与<span lang="EN-US">JDK 1.1.6</span>、<span lang="EN-US">Java 2</span>标准版（<span lang="EN-US">J2SE</span>）平台<span lang="EN-US">1.2.x</span>和<span lang="EN-US">1.3.x</span>协同工作。<span lang="EN-US"><br>
</span>注意：在安装了<span lang="EN-US">Sun</span>公司的<span lang="EN-US">JavaMail</span>工具后，会在演示目录下看到许多示例程序。<span lang="EN-US"><br>
</span>安装<span lang="EN-US">JavaMail 1.2<br>
</span>要使用<span lang="EN-US">JavaMail 1.2 API</span>，可以下载<span lang="EN-US">JavaMail
1.2</span>工具，然后解压缩<span lang="EN-US">javamail-1_2.zip</span>文件，并把<span lang="EN-US">mail.jar</span>文件添加到典型安装路径下。<span lang="EN-US">JavaMail 1.2</span>工具带有<span lang="EN-US">SMTP</span>、<span lang="EN-US">IMAP4</span>和<span lang="EN-US">POP3</span>提供程序以及核心类。<span lang="EN-US"><br>
</span>安装完<span lang="EN-US">JavaMail 1.2</span>后，再安装<span lang="EN-US">JavaBeans
Activation Framework</span>。<span lang="EN-US"><br>
</span>安装<span lang="EN-US">JavaMail 1.1.3<br>
</span>要 使用<span lang="EN-US">JavaMail 1.1.3 API</span>，可以下载<span lang="EN-US">JavaMail
1.1.3</span>工具，然后解压缩<span lang="EN-US">javamail1_1_3.zip</span>文件，并把<span lang="EN-US">mail.jar</span>文件添加到典型安装路径下。<span lang="EN-US">JavaMail 1.1.3</span>工具带有<span lang="EN-US">SMTP</span>和<span lang="EN-US">IMAP4</span>提供程序以及核心类。<span lang="EN-US"><br>
</span>如果您想用<span lang="EN-US">JavaMail 1.1.3</span>访问<span lang="EN-US">POP</span>服务器，需要下载并安装<span lang="EN-US">POP3</span>提供程序。<span lang="EN-US">Sun</span>公司拥有一个独立于<span lang="EN-US"> JavaMail </span>工具的提供程序。在下载并解压缩<span lang="EN-US">pop31_1_1.zip</span>文件后，也还需要把<span lang="EN-US">pop3.jar</span>添加到典型安装路径下。<span lang="EN-US"><br>
</span>安装完<span lang="EN-US">JavaMail 1.1.3</span>后，再安装<span lang="EN-US">JavaBeans
Activation Framework</span>。<span lang="EN-US"><br>
</span>安装<span lang="EN-US">JavaBeans Activation Framework<br>
JavaMail API</span>的所有版本都需要<span lang="EN-US">JavaBeans Activation Framework</span>（<span lang="EN-US">JavaBeans</span>激活框架），这种框架提供了对输入任意数据块的支持，并能相应地对其进行处理。看上去效果好像不太好，但该框架是
在当今的许多浏览器和邮件工具中可以找到的基本<span lang="EN-US">MIME</span>类型支持。下载该框架后，解压缩<span lang="EN-US">jaf1_0_1.zip</span>文件，并将<span lang="EN-US">activation.jar </span>文件添加到典型安装路径下。<span lang="EN-US"><br>
</span>对于<span lang="EN-US">JavaMail 1.2</span>用户，现在应该把<span lang="EN-US">mail.jar</span>和<span lang="EN-US">activation.jar</span>文件添加到典型安装路径下。<span lang="EN-US"><br>
</span>对于<span lang="EN-US">JavaMail 1.1.3</span>用户，现在应该把<span lang="EN-US">mail.jar</span>、<span lang="EN-US">pop3.jar</span>和<span lang="EN-US">activation.jar</span>添加到典型安装路径下。如果您不打算使用<span lang="EN-US">POP3</span>，就不需要把<span lang="EN-US">pop3.jar</span>文件添加到典型安装路径下。<span lang="EN-US"><br>
</span>如果您不想更改安装路径环境变量，可以把<span lang="EN-US">JAR</span>文件复制到<span lang="EN-US">Java</span>运行时环境（<span lang="EN-US">JRE</span>）目录下的<span lang="EN-US">lib/ext</span>目录下。例如，对于<span lang="EN-US">J2SE 1.3</span>版本，<span lang="EN-US">Windows</span>平台上的默认目录应该是<span lang="EN-US">C:\jdk1.3\jre\lib\ext</span>。<span lang="EN-US"><br>
</span>使用<span lang="EN-US">Java 2</span>企业版<span lang="EN-US"><br>
</span>如果您使用的是<span lang="EN-US">J2EE</span>，则在使用基本<span lang="EN-US">JavaMail API</span>时，不需要做什么特殊的工作；<span lang="EN-US">JavaMail API</span>带有<span lang="EN-US">J2EE</span>类。只要确保<span lang="EN-US">j2ee.jar</span>文件位于典型安装路径下，并完成了所有的设置工作。<span lang="EN-US"> <br>
</span>对 于<span lang="EN-US">J2EE 1.2.1</span>，<span lang="EN-US">POP3</span>提供程序是单独提供的，因此需要下载该提供程序，并按安装<span lang="EN-US">JavaMail 1.1.3</span>的步骤，在<span lang="EN-US">J2EE 1.2.1</span>中包含<span lang="EN-US">POP3</span>提供程序。<span lang="EN-US">J2EE 1.3</span>的用户会获得<span lang="EN-US">J2EE</span>和<span lang="EN-US">POP3</span>提供程序，因而不需要对<span lang="EN-US">POP3</span>提供程序执行独立安装。使用这两种版本的<span lang="EN-US">J2EE</span>用户，都不需要安装<span lang="EN-US"> JavaBeans Activation Framework</span>。<span lang="EN-US"><br>
</span>练习<span lang="EN-US"><br>
</span>设置您的<span lang="EN-US"> JavaMail </span>环境。<span lang="EN-US"><br>
</span>复习核心类<span lang="EN-US"><br>
</span>在 开始深入研究<span lang="EN-US">JavaMail</span>类之前，首先让用户浏览一下构成<span lang="EN-US">API</span>的核心类：会话、消息、地址、验证程序、传输，存储和文件夹。所有这些类都可以在<span lang="EN-US"> JavaMail API</span>即<span lang="EN-US">javax.mail</span>的顶层包中找到，尽管您将频繁地发现您自己使用的子类是在<span lang="EN-US">javax.mail.internet</span>包中找到的。<span lang="EN-US"><br>
Session</span>类<span lang="EN-US"><br>
Session</span>类定义了一个基本的邮件会话。通过该会话可让别的工作顺利执行。<span lang="EN-US">Session</span>对象利用<span lang="EN-US">java.util.Properties</span>对象获取诸如邮件服务器、用户名、密码等信息，以及其他可在整个应用程序中共享的信息。<span lang="EN-US"><br>
Session</span>类的构造器是私有的。您可以获得一个可被<span lang="EN-US">getDefaultInstance()</span>方法共享的单一的默认会话：<span lang="EN-US"><br>
Properties props = new Properties();<br>
// fill props with any information<br>
Session session = Session.getDefaultInstance(props, null);<br>
</span>或者，您可以用<span lang="EN-US">getInstance()</span>方法创建一个独特的会话：<span lang="EN-US"><br>
Properties props = new Properties();<br>
// fill props with any information<br>
Session session = Session.getInstance(props, null);<br>
</span>这两种情形下的<span lang="EN-US">null</span>参数都是一种<span lang="EN-US">Authenticator</span>对象，它不是在此时使用的。详细信息请参阅其后的<span lang="EN-US">“Autherticator”</span>一节。<span lang="EN-US"><br>
</span>在大多数情况下，使用共享会话就足够了，即使为多个用户邮箱处理邮件会话也是如此。您可以在通信过程的后面一步添加上用户名和密码的组合，并保持所有的一切是独立的。<span lang="EN-US"><br>
Message</span>类<span lang="EN-US"><br>
</span>一 旦创建了自己的<span lang="EN-US">Session</span>对象，就是该去创建要发送的消息的时候了。这时就要用到消息类型。作为一个抽象类，您必须操作一个子类，在大多数情况下，该
子类是<span lang="EN-US">javax.mail.internet.MimeMessage</span>。一个<span lang="EN-US">MimeMessage</span>是一种理解<span lang="EN-US">MIME</span>类型和报头（在不同的<span lang="EN-US">RFC</span>文档 中均有定义）的消息。消息的报头被严格限制成只能使用<span lang="EN-US">US-ASCII</span>字符，尽管非<span lang="EN-US">ASCII</span>字符可以被编码到某些报头字段中。<span lang="EN-US"><br>
</span>可以通过将<span lang="EN-US">Session</span>对象传递给<span lang="EN-US">MimeMessage</span>构造器的方法来创建消息：<span lang="EN-US"><br>
MimeMessage message = new MimeMessage(session);<br>
</span>注意：还有其他的构造器，像用于创建消息的源于<span lang="EN-US">RFC822</span>格式化的输入流的构造器。<span lang="EN-US"><br>
</span>一旦创建了消息，就可以设置其各个部分，如<span lang="EN-US">Message(</span>消息<span lang="EN-US">)</span>实现<span lang="EN-US">Part</span>（部分）接口（以<span lang="EN-US">MimeMessage</span>实现<span lang="EN-US">MimePart</span>）。设置内容的基本机制是<span lang="EN-US">setContent()</span>方法，它带有表示内容和<span lang="EN-US">MIME</span>类型的参数：<span lang="EN-US"><br>
message.setContent("Hello", "text/plain");<br>
</span>但是，如果正在使用<span lang="EN-US"> MimeMessage</span>，并且您的消息是纯文本，那么您就可以使用<span lang="EN-US">setText()</span>方法。该方法只需要一个表示实际内容的参数，默认的<span lang="EN-US">MIME</span>类型为纯文本：<span lang="EN-US"><br>
message.setText("Hello");<br>
</span>对于纯文本消息，<span lang="EN-US">setText()</span>方法更常常被用来设置内容。要发送其他类型的消息，如<span lang="EN-US">HTML</span>消息，就要使用<span lang="EN-US">setContent</span>方法<span lang="EN-US">()</span>。现在用的更多的是<span lang="EN-US">HTML</span>消息。<span lang="EN-US"><br>
</span>要设置主题，可以使用<span lang="EN-US">setSubject()</span>方法：<span lang="EN-US"><br>
message.setSubject("First");<br>
Address</span>类<span lang="EN-US"><br>
</span>一旦创建了会话和消息，并为消息填充了内容，就需要用<span lang="EN-US">Address</span>类为您的信件标上地址了。同<span lang="EN-US">Message</span>类一样，<span lang="EN-US">Address</span>类也是一种抽象类。您可以使用<span lang="EN-US">javax.mail.internet.InternetAddress</span>类。<span lang="EN-US"><br>
</span>要创建只带有电子邮件地址的地址，可以把电子邮件地址传递给<span lang="EN-US">Address</span>类的构造器：<span lang="EN-US"><br>
Address address = new InternetAddress("<a href="mailto:president@whitehouse.gov">president@whitehouse.gov</a>");<br>
</span>如果想让一个名字出现在电子邮件地址后，也可以将其传递给构造器：<span lang="EN-US"><br>
Address address = new InternetAddress("<a href="mailto:president@whitehouse.gov">president@whitehouse.gov</a>",
"George Bush");<br>
</span>您要为消息的<span lang="EN-US">from</span>（发送者）字段和<span lang="EN-US">to</span>（接收者）字段创建地址对象。除非您的邮件服务器阻止这样做，否则要在发送的消息中注明该消息的发送者。<span lang="EN-US"><br>
</span>一旦创建好了地址，有两种方法可让您将地址与消息连接起来。为了鉴别发送者，您可以使用<span lang="EN-US">setFrom()</span>和<span lang="EN-US">setReplyTo()</span>方法。<span lang="EN-US"><br>
message.setFrom(address)<br>
</span>如果您的消息需要显示多个地址来源，则可以使用<span lang="EN-US">addFrom()</span>方法：<span lang="EN-US"><br>
Address address[] = ...;<br>
message.addFrom(address);<br>
</span>为了鉴别消息接收者，您可以使用<span lang="EN-US">addRecipient()</span>方法。该方法除了需要一个地址参数外，还需要一个<span lang="EN-US">Message.RecipientType</span>属性（消息的接收类型）。<span lang="EN-US"><br>
message.addRecipient(type, address)<br>
</span>地址的<span lang="EN-US">3</span>种预定义类型如下：<span lang="EN-US"><br>
· Message.RecipientType.TO <br>
· Message.RecipientType.CC <br>
· Message.RecipientType.BCC <br>
</span>因此，如果一条消息将发送给副总统，同时还将发送该消息的副本给第一夫人，则采用下面的代码：<span lang="EN-US"><br>
Address toAddress = new InternetAddress("<a href="mailto:vice.president@whitehouse.gov">vice.president@whitehouse.gov</a>");<br>
Address ccAddress = new InternetAddress("<a href="mailto:first.lady@whitehouse.gov">first.lady@whitehouse.gov</a>");<br>
message.addRecipient(Message.RecipientType.TO, toAddress);<br>
message.addRecipient(Message.RecipientType.CC, ccAddress);<br>
JavaMail API</span>没有提供检查电子邮件地址有效性的机制。您可以自己编写支持扫描有效字符（在<span lang="EN-US">RFC 822</span>文档中所定义的）的程序或检验<span lang="EN-US">MX</span>（邮件交换）记录，这些都超越了<span lang="EN-US">JavaMail API</span>的范围。<span lang="EN-US"><br>
Authenticator</span>类<span lang="EN-US"><br>
</span>与<span lang="EN-US">java.net </span>类一样，<span lang="EN-US">JavaMail API</span>可以利用<span lang="EN-US">Authenticator</span>（验证程序）类通过用户名和密码来访问受保护的资源。对于<span lang="EN-US">JavaMail
API</span>来说，这种受保护的资源是指邮件服务器。<span lang="EN-US">JavaMail</span>的<span lang="EN-US">Authenticator</span>类可以在<span lang="EN-US">javax.mail</span>包中找到，并有别于同名的<span lang="EN-US"> java.net</span>类。当<span lang="EN-US">JavaMail API</span>在<span lang="EN-US">Java 1.1</span>下工作时，<span lang="EN-US">JavaMail</span>和<span lang="EN-US">java.net</span>不会共享同一个<span lang="EN-US">Authenticator</span>类名称，这是因为<span lang="EN-US">Java 1.1</span>中不含有<span lang="EN-US">java.net</span>。<span lang="EN-US"><br>
</span>要使用<span lang="EN-US">Authenticator</span>类，您可以使用该抽象类的子类，并通过<span lang="EN-US"> getPasswordAuthentication()</span>方法返回一个<span lang="EN-US">PasswordAuthentication</span>实例。在创建时，您必须用会话记录<span lang="EN-US"> Authentication</span>类。其后，当需要进行身份验证时，会通知您的<span lang="EN-US">Authenticator</span>。会弹出一个窗口，或从一个配置文件（尽管不加密就
不安全）中读取用户名和密码，并把它们作为一个<span lang="EN-US">PasswordAuthentication</span>对象返回给调用程序。<span lang="EN-US"><br>
Properties props = new Properties();<br>
// fill props with any information<br>
Authenticator auth = new MyAuthenticator();<br>
Session session = Session.getDefaultInstance(props, auth);<br>
Transport</span>类<span lang="EN-US"><br>
</span>发送消息的最后一步操作是使用<span lang="EN-US">Transport</span>类。该类使用特定于协议（通常是<span lang="EN-US">SMTP</span>）的语言来发送消息。它是一个抽象类，其操作与<span lang="EN-US">Session</span>类有些相似。您可以通过只调用静态的<span lang="EN-US">send()</span>方法来使用该类的默认版本：<span lang="EN-US"><br>
Transport.send(message);<br>
</span>或者，您可以从用于您的协议的会话中获取一个特定的实例，然后传递用户名和密码（不必要时可以为空）并发送消息，最后关闭连接：<span lang="EN-US"><br>
message.saveChanges(); // implicit with send()<br>
Transport transport = session.getTransport("smtp");<br>
transport.connect(host, username, password);<br>
transport.sendMessage(message, message.getAllRecipients());<br>
transport.close();<br>
</span>当您需要发送多个消息时，建议采用后一种方法，因为它将保持消息间活动服务器的连接。而基本的<span lang="EN-US">send()</span>机制会为每一个方法调用都建立一条独立的连接。<span lang="EN-US"><br>
</span>注意：要查看经过邮件服务器邮件命令，可以用<span lang="EN-US">session.setDebug(true)</span>方法设置调试标志。<span lang="EN-US"><br>
Store</span>和<span lang="EN-US">Folder</span>类<span lang="EN-US"><br>
</span>使用<span lang="EN-US">Session</span>类来获取消息，开始时与发送消息很相似。但是，在获取会话后，很有可能使用用户名和密码或<span lang="EN-US">Authenticator</span>类来连接<span lang="EN-US">Store</span>类。与<span lang="EN-US">Transport</span>类一样，您要告诉<span lang="EN-US">Store</span>类将使用什么协议：<span lang="EN-US"><br>
// Store store = session.getStore("imap");<br>
Store store = session.getStore("pop3");<br>
store.connect(host, username, password);<br>
</span>在连接<span lang="EN-US">Store</span>类后，就可以获取一个<span lang="EN-US">Folder</span>类，在读取其中的消息前必须先打开该类。<span lang="EN-US"><br>
Folder folder = store.getFolder("INBOX");<br>
folder.open(Folder.READ_ONLY);<br>
Message message[] = folder.getMessages();<br>
</span>对于<span lang="EN-US">POP3</span>协议，惟一可用的文件夹是<span lang="EN-US">INBOX</span>。如果使用的是<span lang="EN-US">IMAP</span>协议，则可以使用其他的文件夹。<span lang="EN-US"><br>
</span>注意：<span lang="EN-US">Sun</span>公司的提供程序本来想提供方便。而<span lang="EN-US">Message
message[]=folder.getMessages();</span>这条语句却是一种从服务器逐条读取消息的缓慢操作，所以仅当您确实需要获取消息部分（该内容是所检索消息的内容）时可以使用这条语句。<span lang="EN-US"><br>
</span>一旦读取消息，就可以使用<span lang="EN-US">getContent()</span>方法获取其内容，或使用<span lang="EN-US">writeTo()</span>方法将其内容写到一个流中。<span lang="EN-US">getContent()</span>方法只获取消息内容，而<span lang="EN-US">writeTo()</span>方法则还会输出报头。<span lang="EN-US"><br>
System.out.println(((MimeMessage)message).getContent());<br>
</span>一旦您阅读完邮件，就可以关闭对文件夹和存储的连接。<span lang="EN-US"><br>
folder.close(aBoolean);<br>
store.close();<br>
</span>传递给文件夹的<span lang="EN-US">close()</span>方法的布尔变量指定了是否通过清除已删除的消息来更新文件夹。<span lang="EN-US"><br>
</span>继续前进<span lang="EN-US"><br>
</span>实 际上，理解使用这<span lang="EN-US">7</span>个类的方式，是使用<span lang="EN-US">JavaMail
API</span>处理几乎所有事情所需要的全部内容。用这<span lang="EN-US">7</span>个类以外的方式构建的<span lang="EN-US">JavaMail API</span>，其大多数功能都是以几乎完全相同或特定的方式来执行任务的，就好像内容是附件。特定的任务，如：搜索、隔离等将在后面进行介绍。<span lang="EN-US"><br>
</span>使用<span lang="EN-US">JavaMail API<br>
</span>您已经看到了如何操作<span lang="EN-US">JavaMail API</span>的核心部分。在下面几节中，您将学习如何连接几个部分以执行特定的任务。<span lang="EN-US"><br>
</span>发送消息<span lang="EN-US"><br>
</span>发送电子邮件消息涉及到获取会话、创建和填充消息并发送消息这些操作。您可以在获取<span lang="EN-US">Session</span>时，通过为要传递的<span lang="EN-US">Properties</span>对象设置<span lang="EN-US">mail.smtp.host</span>属性来指定您的<span lang="EN-US">SMTP</span>服务器。<span lang="EN-US"><br>
String host = ...;<br>
String from = ...;<br>
String to = ...;<br>
// Get system properties<br>
Properties props = System.getProperties();<br>
// Setup mail server<br>
props.put("mail.smtp.host", host);<br>
// Get session<br>
Session session = Session.getDefaultInstance(props, null);<br>
// Define message<br>
MimeMessage message = new MimeMessage(session);<br>
message.setFrom(new InternetAddress(from));<br>
message.addRecipient(Message.RecipientType.TO, <br>
new InternetAddress(to));<br>
message.setSubject("Hello JavaMail");<br>
message.setText("Welcome to JavaMail");<br>
// Send message<br>
Transport.send(message);<br>
</span>您应该在<span lang="EN-US">try-catch</span>块中编写代码，以在创建消息并发送它时可以抛出一个异常。<span lang="EN-US"><br>
</span>练习<span lang="EN-US"><br>
</span>发送您的第一个消息<span lang="EN-US"><br>
</span>获取消息<span lang="EN-US"><br>
</span>对于阅读邮件来说，首先您要获取一个会话，然后获取并连接到一个相应的用于您的收件箱的存储上，接着打开相应的文件夹，再获取消息。同时，不要忘记了操作完成后关闭连接。<span lang="EN-US"><br>
String host = ...;<br>
String username = ...;<br>
String password = ...;<br>
// Create empty properties<br>
Properties props = new Properties();<br>
// Get session<br>
Session session = Session.getDefaultInstance(props, null);<br>
// Get the store<br>
Store store = session.getStore("pop3");<br>
store.connect(host, username, password);<br>
// Get folder<br>
Folder folder = store.getFolder("INBOX");<br>
folder.open(Folder.READ_ONLY);<br>
// Get directory<br>
Message message[] = folder.getMessages();<br>
for (int i=0, n=message.length; i&lt;n; i++) {<br>
System.out.println(i + ": " + message[i].getFrom()[0] <br>
+ "\t" + message[i].getSubject());<br>
}<br>
// Close connection <br>
folder.close(false);<br>
store.close();<br>
</span>每一条消息执行何种操作取决于自己决定。上面的代码块只是显示了消息的发送者和主题。从技术上讲，发送者地址列表可以为空，此时<span lang="EN-US">getFrom()[0]</span>调用会抛出一个异常。<span lang="EN-US"><br>
</span>为了显示整条消息，您可以提示用户在看完消息的发送者和主题字段后，如果想看到消息的内容，可以再调用消息的<span lang="EN-US">writeTo()</span>方法。<span lang="EN-US"><br>
BufferedReader reader = new BufferedReader (<br>
new InputStreamReader(System.in));<br>
// Get directory<br>
Message message[] = folder.getMessages();<br>
for (int i=0, n=message.length; i&lt;n; i++) {<br>
System.out.println(i + ": " + message[i].getFrom()[0] <br>
+ "\t" + message[i].getSubject());<br>
System.out.println("Do you want to read message? " +<br>
"[YES to read/QUIT to end]");<br>
String line = reader.readLine();<br>
if ("YES".equals(line)) {<br>
message[i].writeTo(System.out);<br>
} else if ("QUIT".equals(line)) {<br>
break;<br>
}<br>
}<br>
</span>练习<span lang="EN-US"><br>
</span>检查邮件<span lang="EN-US"><br>
</span>删除消息和标志<span lang="EN-US"><br>
</span>删除消息涉及到操作与消息关联的标志。对不同的状态有不同的标志，有些标志是系统定义的，有些则是由用户定义的。预定义的标志都是在内部类<span lang="EN-US">Flags.Flag</span>中定义的，如下所示：<span lang="EN-US"><br>
· Flags.Flag.ANSWERED <br>
· Flags.Flag.DELETED <br>
· Flags.Flag.DRAFT <br>
· Flags.Flag.FLAGGED <br>
· Flags.Flag.RECENT <br>
· Flags.Flag.SEEN <br>
· Flags.Flag.USER <br>
</span>仅 仅因为标志存在，并不表示标志为所有的邮件服务器<span lang="EN-US">/</span>提供程序所支持。例如，除了删除消息外，<span lang="EN-US">POP</span>协议对它们都不支持。检查新邮件不是<span lang="EN-US">POP</span>的任务，但它 已内置到邮件客户程序中。要搞清楚什么标志受到支持，可以使用<span lang="EN-US">getPermanentFlags()</span>方法来询问文件夹。<span lang="EN-US"><br>
</span>要删除消息，需要为消息设置<span lang="EN-US">DELETE</span>标志：<span lang="EN-US"><br>
message.setFlag(Flags.Flag.DELETED, true);<br>
</span>第一次以<span lang="EN-US">READ_WRITE</span>（读<span lang="EN-US">-</span>写）模式打开文件夹：<span lang="EN-US"><br>
folder.open(Folder.READ_WRITE);<br>
</span>然后，处理完了所有的消息，请关闭文件夹，并传递<span lang="EN-US">true</span>值以擦去删除的消息。<span lang="EN-US"><br>
folder.close(true);<br>
</span>用 户可使用<span lang="EN-US">Folder</span>类的<span lang="EN-US">expunge()</span>方法来删除消息。但是，该方法对<span lang="EN-US">Sun</span>公司的<span lang="EN-US">POP3</span>提供程序不起作用。其他提供程序或许能也或许不能实现其 功能。它更有可能适用于<span lang="EN-US">IMAP</span>提供程序。由于<span lang="EN-US">POP</span>只支持对收件箱的简单访问，使用<span lang="EN-US">Sun</span>公司的提供程序时，您将不得不关闭文件夹以删除消息。<span lang="EN-US"><br>
</span>要移去标志，只需传递一个<span lang="EN-US">false</span>值给<span lang="EN-US">setFlag()</span>方法。要看看是否设置了某个标志，可以使用<span lang="EN-US">isSet()</span>进行检查。<span lang="EN-US"><br>
</span>自我验证<span lang="EN-US"><br>
</span>先前学到的是使用<span lang="EN-US">Authenticator</span>类，以在需要时提示输入用户名和密码，而不是以字符串的形式传入它们。这里，您将真正看到如何更加充分地使用验证。<span lang="EN-US"><br>
</span>不需使用主机、用户名和密码连接到<span lang="EN-US">Store</span>，您可以配置<span lang="EN-US">Properties</span>带有主机，并告诉<span lang="EN-US">Session</span>关于您自定义的<span lang="EN-US">Authenticator</span>实例，如下所示：<span lang="EN-US"><br>
// Setup properties<br>
Properties props = System.getProperties();<br>
props.put("mail.pop3.host", host);<br>
// Setup authentication, get session<br>
Authenticator auth = new PopupAuthenticator();<br>
Session session = Session.getDefaultInstance(props, auth);<br>
// Get the store<br>
Store store = session.getStore("pop3");<br>
store.connect();<br>
</span>然 后您可以使用<span lang="EN-US">Authenticator</span>类的子类，并通过<span lang="EN-US">getPasswordAuthentication()</span>方法返回一个<span lang="EN-US"> PasswordAuthentication</span>对象。下面是这种实现的一个例子，其中一个字段同时适用于两部分内容。它不是一个<span lang="EN-US">Project Swing</span>指南，只是在一个字段中输入了两部分内容，它们是用逗号隔开的。<span lang="EN-US"><br>
import javax.mail.*;<br>
import javax.swing.*;<br>
import java.util.*;<br>
public class PopupAuthenticator extends Authenticator {<br>
public PasswordAuthentication getPasswordAuthentication() {<br>
String username, password;<br>
String result = JOptionPane.showInputDialog(<br>
"Enter 'username,password'");<br>
StringTokenizer st = new StringTokenizer(result, ",");<br>
username = st.nextToken();<br>
password = st.nextToken();<br>
return new PasswordAuthentication(username, password);<br>
}<br>
}<br>
</span>由于<span lang="EN-US">PopupAuthenticator</span>依赖于<span lang="EN-US">Swing</span>，因而将会启动用于<span lang="EN-US">AWT</span>的事件处理线程。这在本质上要求您在代码中添加一个对<span lang="EN-US">System.exit()</span>的调用，以终止程序的执行。<span lang="EN-US"><br>
</span>回复消息<span lang="EN-US"><br>
Message </span>类包含一个<span lang="EN-US">reply()</span>方法，以用正确的接收者和主题（添加<span lang="EN-US">“Re:</span>：<span lang="EN-US">”</span>，如果没有的话）配置一条新消息。该方法不会为消息添加任何内容，只是为新的接
收者复制发送者或回复到的报头。该方法使用一个布尔型参数，提示是否只回复给发送者（<span lang="EN-US">false</span>）或回复给所有人<span lang="EN-US">(true)</span>。<span lang="EN-US"><br>
MimeMessage reply = (MimeMessage)message.reply(false);<br>
reply.setFrom(new InternetAddress("<a href="mailto:president@whitehouse.gov">president@whitehouse.gov</a>"));<br>
reply.setText("Thanks");<br>
Transport.send(reply);<br>
</span>在发送消息时要配置回复到地址，可使用<span lang="EN-US">setReplyTo()</span>方法。<span lang="EN-US"><br>
</span>练习<span lang="EN-US"><br>
</span>回复邮件<span lang="EN-US"><br>
</span>转发消息<span lang="EN-US"><br>
</span>转发消息涉及的内容要稍微多一点，没有一个专门用于转发消息的方法，您可以通过处理组成消息的各个部分来创建要转发的消息。<span lang="EN-US"><br>
</span>一 条邮件消息可由多个部分组成，每一部分是一个<span lang="EN-US">BodyPart</span>（报文部分），或更特殊一点，在操作<span lang="EN-US">MIME</span>消息时则是<span lang="EN-US">MimeBodyPart</span>。不同的报 文部分组合到一个称为<span lang="EN-US">Multipart</span>的容器中，或者又更特殊一点，是一个<span lang="EN-US">MimeMultipart</span>容器。要转发消息，您要创建一个用于消息文本的部
分，和用于要转发的消息的第二个部分，并将这两个部分组合成一个<span lang="EN-US">multipart</span>（多个部分）。然后您可以把这个<span lang="EN-US">multipart</span>添加到一个合适的注 明地址的消息中并发送它。<span lang="EN-US"><br>
</span>这就是转发消息的本质。要把一条消息的内容复制给另一条消息，只需通过它的<span lang="EN-US">DataHandler</span>类复制即可，它是出自于<span lang="EN-US">JavaBeans Activation Framework</span>的一个类。<span lang="EN-US"><br>
// Create the message to forward<br>
Message forward = new MimeMessage(session);<br>
// Fill in header<br>
forward.setSubject("Fwd: " + message.getSubject());<br>
forward.setFrom(new InternetAddress(from));<br>
forward.addRecipient(Message.RecipientType.TO, <br>
new InternetAddress(to));<br>
// Create your new message part<br>
BodyPart messageBodyPart = new MimeBodyPart();<br>
messageBodyPart.setText(<br>
"Here you go with the original message:\n\n");<br>
// Create a multi-part to combine the parts<br>
Multipart multipart = new MimeMultipart();<br>
multipart.addBodyPart(messageBodyPart);<br>
// Create and fill part for the forwarded content<br>
messageBodyPart = new MimeBodyPart();<br>
messageBodyPart.setDataHandler(message.getDataHandler());<br>
// Add part to multi part<br>
multipart.addBodyPart(messageBodyPart);<br>
// Associate multi-part with message<br>
forward.setContent(multipart);<br>
// Send message<br>
Transport.send(forward);<br>
</span>操作附件<span lang="EN-US"><br>
</span>附件是与邮件消息关联的资源，通常保存在消息之外，如：一个文本文件，电子表格或图片。对于像<span lang="EN-US">Eudora</span>和<span lang="EN-US">Pine</span>之类的常用邮件程序，您可以通过<span lang="EN-US">JavaMail API</span>把资源附加到邮件消息上，并在您接收消息时获取附件。<span lang="EN-US"><br>
</span>发送附件<span lang="EN-US"><br>
</span>发 送附件与转发消息非常相似，您要创建组成完整消息的各个部分。在创建好第一个部分即消息文本之后，您添加的用<span lang="EN-US">DataHandler</span>类处理的其他部分就是
您的附件，而不是转发消息中的共享处理程序。当您从一个文件读取附件时，附件的数据资源是<span lang="EN-US">FileDataSource</span>；从<span lang="EN-US">URL</span>读取时，则是<span lang="EN-US"> URLDataSource</span>。一旦您有了自己的<span lang="EN-US">DataSource</span>，在将其通过<span lang="EN-US">setDataHandler()</span>方法最终附加到<span lang="EN-US">BodyPart</span>上之 前，只需将其传递给<span lang="EN-US">DataHandler</span>类的构造器即可。假定您想保留附件的原始文件名，要做的最后一件事就是用<span lang="EN-US">BodyPart</span>类的<span lang="EN-US"> setFileName()</span>方法设置与附件关联的文件名。所有这些操作如下所示：<span lang="EN-US"><br>
// Define message<br>
Message message = new MimeMessage(session);<br>
message.setFrom(new InternetAddress(from));<br>
message.addRecipient(Message.RecipientType.TO, <br>
new InternetAddress(to));<br>
message.setSubject("Hello JavaMail Attachment");<br>
// Create the message part <br>
BodyPart messageBodyPart = new MimeBodyPart();<br>
// Fill the message<br>
messageBodyPart.setText("Pardon Ideas");<br>
Multipart multipart = new MimeMultipart();<br>
multipart.addBodyPart(messageBodyPart);<br>
// Part two is attachment<br>
messageBodyPart = new MimeBodyPart();<br>
DataSource source = new FileDataSource(filename);<br>
messageBodyPart.setDataHandler(new DataHandler(source));<br>
messageBodyPart.setFileName(filename);<br>
multipart.addBodyPart(messageBodyPart);<br>
// Put parts in message<br>
message.setContent(multipart);<br>
// Send the message<br>
Transport.send(message);<br>
</span>在消息中包含附件时，如果您的程序是一个<span lang="EN-US">servlet</span>，您的用户就必须上传附件，并告诉您要把消息发送到什么位置。上传的每一个文件都可以用一个表单来处理，该表单是以<span lang="EN-US">multipart/</span>表单数据（<span lang="EN-US">form-data</span>）来编码的。<span lang="EN-US"><br>
&lt;FORM ENCTYPE="multipart/form-data" <br>
method=post action="/myservlet"&gt; <br>
&lt;INPUT TYPE="file" NAME="thefile"&gt;<br>
&lt;INPUT TYPE="submit" VALUE="Upload"&gt;<br>
&lt;/FORM&gt;<br>
</span>注意：消息的大小要受到您的<span lang="EN-US">SMTP</span>服务器的限制，而不是由<span lang="EN-US">JavaMail
API</span>限制的。如果出现了问题，可以通过设置<span lang="EN-US">ms</span>和<span lang="EN-US">mx</span>参数来考虑增加<span lang="EN-US">Java</span>堆区的空间尺寸。<span lang="EN-US"><br>
</span>练习<span lang="EN-US"><br>
</span>发送附件<span lang="EN-US"><br>
</span>获取附件<span lang="EN-US"><br>
</span>从 消息中取出附件比发送附件涉及的操作要稍微多一点，而<span lang="EN-US">MIME</span>没有简单的附件概念。当消息带有附件时，消息的内容就是一个<span lang="EN-US">Multipart</span>对象。然后需 要处理各个部分，以获取主要内容和附件。通过<span lang="EN-US">part.getDisposition()</span>方法标记上<span lang="EN-US">Part.ATTACHMENT</span>配置的部分显然就是附 件。同时，附件也可以不带有配置（和非文本<span lang="EN-US">MIME</span>类型）或<span lang="EN-US">Part.INLINE</span>配置。当配置是<span lang="EN-US">Part.ATTACHMENT</span>或<span lang="EN-US"> Part.INLINE</span>时，您可以脱离该消息部分的内容将其保存起来。只需通过<span lang="EN-US">getFileName()</span>方法获取原始文件名，并通过<span lang="EN-US"> getInputStream()</span>方法获取输入流即可。<span lang="EN-US"><br>
Multipart mp = (Multipart)message.getContent();<br>
for (int i=0, n=multipart.getCount(); i&lt;n; i++) {<br>
Part part = multipart.getBodyPart(i));<br>
String disposition = part.getDisposition();<br>
if ((disposition != null) &amp;&amp; <br>
((disposition.equals(Part.ATTACHMENT) || <br>
(disposition.equals(Part.INLINE))) {<br>
saveFile(part.getFileName(), part.getInputStream());<br>
}<br>
}<br>
saveFile()</span>方法只用于根据文件名创建一个文件，从输入流中读取字节，并将它们写入一个文件中去。如果文件已存在，将在文件名后添加一个编号，直到找到一个不存在的文件为止。<span lang="EN-US"><br>
// from saveFile()<br>
File file = new File(filename);<br>
for (int i=0; file.exists(); i++) {<br>
file = new File(filename+i);<br>
}<br>
</span>上面的代码介绍了消息的各个部分被标上相应的标志的一个最简单的例子。要想包含所有的情况，还要对<span lang="EN-US">disposition</span>值为<span lang="EN-US">null</span>及消息部分为<span lang="EN-US">MIME</span>类型的情况作相应处理。<span lang="EN-US"><br>
if (disposition == null) {<br>
// Check if plain<br>
MimeBodyPart mbp = (MimeBodyPart)part;<br>
if (mbp.isMimeType("text/plain")) {<br>
// Handle plain<br>
} else {<br>
// Special non-attachment cases here of image/gif, text/html, ...<br>
}<br>
...<br>
}<br>
</span>处理<span lang="EN-US">HTML</span>消息<span lang="EN-US"><br>
</span>发送基于<span lang="EN-US">HTML</span>的消息比发送纯文本消息要稍微复杂一点，尽管它不需要做大量的工作。它全部取决于您特定的需求。<span lang="EN-US"><br>
</span>发送<span lang="EN-US">HTML</span>消息<span lang="EN-US"><br>
</span>如果您所要做的全部工作是发送一个等价的<span lang="EN-US">HTML</span>文件作为消息，并让邮件阅读者忧心于取出任何嵌入的图片或相关片段，那么就可以使用消息的<span lang="EN-US">setContent()</span>方法，以字符串形式传递消息内容，并把内容类型设置为<span lang="EN-US">text/html</span>。<span lang="EN-US"><br>
String htmlText = "&lt;H1&gt;Hello&lt;/H1&gt;" + <br>
"&lt;img src=\"<a href="http://www.jguru.com/images/logo.gif/">http://www.jguru.com/images/logo.gif\</a>"&gt;";<br>
message.setContent(htmlText, "text/html"));<br>
</span>在 接收端，如果您用<span lang="EN-US">JavaMail API</span>获取消息，在该<span lang="EN-US">API</span>中没有内置任何用于以<span lang="EN-US">HTML</span>格式显示消息的功能。<span lang="EN-US">JavaMail API</span>只以字节流的形式来查看消息。要以<span lang="EN-US">HTML</span>格式显示消息，您必须使用<span lang="EN-US">Swing JeditorPane</span>或某些第<span lang="EN-US">3</span>方<span lang="EN-US">HTML</span>阅读器组件。<span lang="EN-US"><br>
if (message.getContentType().equals("text/html")) {<br>
String content = (String)message.getContent();<br>
JFrame frame = new JFrame();<br>
JEditorPane text = new JEditorPane("text/html", content);<br>
text.setEditable(false);<br>
JScrollPane pane = new JScrollPane(text);<br>
frame.getContentPane().add(pane);<br>
frame.setSize(300, 300);<br>
frame.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);<br>
frame.show();<br>
}<br>
</span>在消息中包含图片<span lang="EN-US"><br>
</span>另一方面，如果您的<span lang="EN-US">HTML</span>消息中嵌入了作为消息一部分的图片，并且您想保持消息内容的完整，就必须把图片看作附件，并用特殊的通信标识符<span lang="EN-US">URL</span>引用该图片，该通信标识符引用的是图片附件的内容<span lang="EN-US">ID</span>报文。<span lang="EN-US"><br>
</span>嵌 入图片的处理与附加一个文件到消息上非常相似，惟一的不同之处在于：您必须区分<span lang="EN-US">MimeMultipart</span>中，哪些部分是在构造器（或通过<span lang="EN-US"> setSubType()</span>方法）通过设置其子类型而使之相关的，以及将图片的内容<span lang="EN-US">ID</span>报头设置成任意字符串，它将在<span lang="EN-US">img</span>标记中用作图片的源路径。下面显 示了一个完整的示例：<span lang="EN-US"><br>
String file = ...;<br>
// Create the message<br>
Message message = new MimeMessage(session);<br>
// Fill its headers<br>
message.setSubject("Embedded Image");<br>
message.setFrom(new InternetAddress(from));<br>
message.addRecipient(Message.RecipientType.TO, <br>
new InternetAddress(to));<br>
// Create your new message part<br>
BodyPart messageBodyPart = new MimeBodyPart();<br>
String htmlText = "&lt;H1&gt;Hello&lt;/H1&gt;" + <br>
"&lt;img src=\"cid:memememe\"&gt;";<br>
messageBodyPart.setContent(htmlText, "text/html");<br>
// Create a related multi-part to combine the parts<br>
MimeMultipart multipart = new MimeMultipart("related");<br>
multipart.addBodyPart(messageBodyPart);<br>
// Create part for the image<br>
messageBodyPart = new MimeBodyPart();<br>
// Fetch the image and associate to part<br>
DataSource fds = new FileDataSource(file);<br>
messageBodyPart.setDataHandler(new DataHandler(fds));<br>
messageBodyPart.setHeader("Content-ID","memememe");<br>
// Add part to multi-part<br>
multipart.addBodyPart(messageBodyPart);<br>
// Associate multi-part with message<br>
message.setContent(multipart);<br>
</span>练习<span lang="EN-US"><br>
</span>发送带有图片的<span lang="EN-US"> HTML </span>消息<span lang="EN-US"><br>
</span>用<span lang="EN-US">SearchTerm</span>搜索<span lang="EN-US"><br>
JavaMail API</span>包含一种可用于创建<span lang="EN-US">SearchTerm</span>（搜索条件）的筛选机制，它可以在<span lang="EN-US">javax.mail.search</span>包中找到。一旦创建了<span lang="EN-US">SearchTerm</span>，您就可以询问某个文件夹匹配的消息，并检索出消息对象数组：<span lang="EN-US"><br>
SearchTerm st = ...;<br>
Message[] msgs = folder.search(st);<br>
</span>有<span lang="EN-US">22</span>种不同的类可用于帮助创建搜索条件。<span lang="EN-US"><br>
· AND</span>条件<span lang="EN-US">(AndTerm</span>类<span lang="EN-US">) <br>
· OR</span>条件<span lang="EN-US">(OrTerm</span>类<span lang="EN-US">) <br>
· NOT</span>条件<span lang="EN-US">(NotTerm</span>类<span lang="EN-US">) <br>
· SENT DATE</span>条件<span lang="EN-US">(SentDateTerm</span>类<span lang="EN-US">) <br>
· CONTENT</span>条件<span lang="EN-US">(BodyTerm</span>类<span lang="EN-US">) <br>
· HEADER</span>条件<span lang="EN-US">(FromTerm / FromStringTerm, RecipientTerm /
RecipientStringTerm, SubjectTerm, etc.) <br>
</span>本质上，您可以为匹配的消息创建一个逻辑表达式，然后进行搜索。例如，下面显示了一条消息的条件搜索示例，该消息带有（部分带有）一个<span lang="EN-US">ADV</span>主题字符串，其发送者字段为<span lang="EN-US"><a href="mailto:friend@public.com">friend@public.com</a></span>。您可能考虑定期运行该查询，并自动删除任何返回的消息。<span lang="EN-US"><br>
SearchTerm st = <br>
new OrTerm(<br>
new SubjectTerm("ADV:"), <br>
new FromStringTerm("<a href="mailto:friend@public.com">friend@public.com</a>"));<br>
Message[] msgs = folder.search(st); </span></p>

<p class="MsoNormal"><span lang="EN-US"><o:p>&nbsp;</o:p></span></p>

<img src ="http://www.blogjava.net/rickhunter/aggbug/25616.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/rickhunter/" target="_blank">千山鸟飞绝</a> 2005-12-27 18:49 <a href="http://www.blogjava.net/rickhunter/articles/25616.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item></channel></rss>