问 从哪里可以学习有关 Internet 邮件的基础知识它是我高效编写 JavaMail 程序需要知道的?
答参见我们的 Web 页中提及的 参考图书 中的一本获得有关 Internet 电子邮件MIMESMTPIMAP 和 POP 等的背景信息
问 如何调试使用 JavaMail API 的应用程序?
答可通过在代码中调用 Session 对象上的 setDebug(true) 方法来打开调试模式这将造成在控制台中打印调试消息包括协议跟蹤信息如果您认为在 JavaMail 中发现了 bug就将这个跟蹤及以下信息发送给我们重生成问题的测试用例使用的平台使用的 JDK 的版本和使用的邮件服务器 (IMAP SMTP) 的名称和版本
问 如何发送带有附件的消息?
答带有附件的消息采用 MIME 多部分消息来表示其中第一部分是消息的主体其他的部分是附件有大量的例子它们展示了如何在演示程序中构建这种消息JavaMail 下载包包含了这些演示程序
问 如何阅读带有附件的消息并保存附件?
答如前面描述在 MIME 中带有附件的消息是作为多部分消息表示的在简单的例子中Message 对象的 getContent 方法的结果将是一个 MimeMultipart 对象多部分对象的第一个主体部分将是消息的主文本其他的主体部分将是附件msgshowjava 演示程序展示了如何在消息中遍历所有的多部分对象并提取各个主体部分数据getDisposition 方法将给你一个提示指出主体部分是否应该内嵌显示或者应该将其考虑成附件(但请注意不是所有的发件人都提供这一信息)
为了将主体部分中的数据保存到文件(比如)请使用 getInputStream 方法来访问附件内容并将数据复制到 FileOutputStream
注意也有一些更复杂的情形也要处理例如一些发件人把主体作为纯文本和 html 发送通常这将作为 multipart/alternative 内容(和 MimeMultipart 对象)出现在简单的文本主体部分的位置中经过数字签名或加密的消息甚至会更复杂处理所有的这些情形可能具有挑战性请参考各种 MIME 规范和我们主页上列出的其他 参考资料
问 什么是中断支持(disconnected support)?
答支持中断操作的邮件客户端将允许用户访问远程消息存储(比如 IMAP)中消息缓存这些消息中的一些消息的(部分)到本地然后断开到服务器的连接当处在断开连接状态中邮件客户端可以访问已经缓存的消息可能也可以删除它们或将它们保存到其他文件夹当邮件客户端下一次连接到远程消息存储时本地所做变更会与远程存储同步同样中断支持可以允许客户端在断开与服务器连接时发送消息在到服务器的连接可用前消息会进行排队也请参阅 RFC
问 如何使用 JavaMail API 来支持中断操作?
答JavaMail API 规范定义了一些接口邮件客户端可以使用这些接口来支持中断操作我们的 IMAP 提供程序实现了这些接口(UIDFolder 接口)
问 我如何使用 JavaMail API 来发送安全的电子邮件?
答JavaMail API 目前不支持发送或接收安全电子邮件JavaMail API 的体系结构使得可以在以后很容易地添加这一支持我们可以添加支持第三方也可以添加支持有关当前电子邮件安全标准(S/MIME 和 PGP)的信息可以从如下站点找到 请浏览我们的 第三方产品 页获取来自其他供应商的解决方案
问 writeTo() 方法生成了消息文件但消息中的一些行既不是数据的规范 MIME 表示(即使用 CRLF 来结束行)又没有使用我的平台的规范行分隔符(例如 UNIX 上的\n)如果我需要这些表示时如何获得它们当中的任何一种表示?
答不管是哪种情形你都将需要创建合适的 FilterOutputStream 对象来传递给 writeTo()FilterOutputStream 将需要接受特定的一些行它们具有任何常见终止符然后写出另外的一些特定行它们只具有期望的行终止符下面是这种过滤器的一些例子NewlineOutputStream 转换到本地平台的行终止符当将消息写到文件时它是有用的CRLFOutputStream 转换到 MIME 规范 CRLF 终止符当需要规范 MIME 格式时(比如计算数字签名)它是有用的
问 我可以使用 JavaMail API 来实现邮件服务器吗?
答JavaMail API 设计目的不是帮你实现邮件服务器但是对你来说一些实用工具类比如 MIME 消息解析类可能是有用的通常您会发现JavaMail API 是在简单而不是在强有力方面出错对于邮件客户端那是合适的但对于邮件服务器结果可能是不同的
问 我可以使用 JavaMail API 在我的邮件服务器上添加新的用户账户删除用户账户或改变用户账户的密码吗?
答JavaMail API 不包括任何工具用于添加删除或修改用户账户在这一方面是没有标准的每个邮件服务器对它的处理是不同的
问 为什么 MimeMessage 类没有实现 Serializable这样我就可以将消息序列化到磁盘并在以后读回它?
答JavaMail API 是在现有电子邮件系统上面设计的并使用了现有的消息格式对于这样的一些实现使用 Java 序列化能力既不是必要的也不是有用的因此不能将它作为 JavaMail API 的目标来考虑
有关序列化 Message 的困难部分是保留某些指针它们指向 Folder(文件夹)Store(存储)和 Session(会话)如果只想保存消息的内容而不是对象本身消息的 writeTo 方法将为你完成这一切如果想根据序列化消息创建整个电子邮件系统您应该能够编写 Message 等的子类并在子类中实现 Serializable
如果想序列化自己的引用了 MimeMessages的其他对象那么你的对象的 writeObject 方法可以使用 MimeMessage 的 writeTo 方法对象的 readObject 方法可以使用 MimeMessage 构造函数该构造函数会得到 InputStream在构造 MimeMessage 时你的类将需要提供一个 Session
问 我如何编写服务提供程序?
答请阅读服务提供程序文档获取一些细节信息通常如果想编写 Store 提供程序那就编写 javaxmailStore 和 javaxmailFolder的子类也可能要编写 javaxmailMessage 及其他一些类的子类对于 Transport 提供程序编写 javaxmailTransport 的子类也可能需要编写 javaxmailMessage 及其他的一些类的子类然后在 javamailproviders 注册表中添加描述提供程序的条目如果对编写特别的服务提供程序感兴趣并且它所针对的协议或邮件系统目前没有得到 JavaMail API 实现的支持请通过 javamail@SunCOM 联系我们
问 我在登录 Microsoft Exchange 服务器时碰到了麻烦我确信正在使用的用户名和密码是正确的我做错了什么?
答当登录 Exchange 时需要使用比简单登录名更多的用户名例如如果你的电子邮件地址是Windows NT 登录名是juserNT 域名是dom而且 Exahange 邮箱名是Joe User那么在使用 JavaMail 登录时你将需要使用用户名 dom\juser\JUser
问 在发送二进制文件前我如何编码它?当收到它时我又如何解码它?
答你不必这样的做!JavaMail 将自动决定合适的编码用于消息部分然后才发送消息而且当读取它们时将自动解码消息部分getInputStream 方法将返回解码数据
问 如果我不需要自己编码和解码附件我应该何时使用 MimeUtility 方法?
答在 JavaMail 没有自动处理的情况下MimeUtility 方法是有用的经常发生的这样的一种情形是文件名的编码基本的 MIME spec(规范)不允许按某种方式编码标题参数值(比如文件名参数)该方式与(比如)编码 Subject(主题)标题相同这限制了参数值从而限制了文件名到 ASCII但一些发件人却实际使用 MIME 文本编码来做非 ASCII 文件名的编码工作想与这种非标准发件人互操作的应用程序可以使用 encodeText 方法来编码文件名然后调用 MimeBodyPartsetFileName 方法而且可以使用 decodeText 方法来解码返回的文件名
问 尽管 JavaMail 完成了所有的编码和解码工作但我仍需要手动控制一些主体部分的编码
答在少数的场合需要控制编码这里有几个方法来重写 JavaMail 的默认行为下面是一个简单的方法在创建整个消息后调用 msgsaveChanges()然后使用像 mbpsetHeader(ContentTransferEncoding base) 的语句来强制对指定主体部分做 base 编码
另一种办法是编写 MimeBodyPart 的子类并重写 updateHeaders 方法让它首先调用 superupdateHeaders()然后像上面那样设置 ContentTransferEncoding 标题
问 为什么 JavaMail 没有在非 ASCII 字符集中正确编码和解码文件名?
答文件名是作为参数存储在 MIME 标题中的形如 =?ISO?B?OTkLUluZmucGRm?= 的编码文件名不是 MIME spec(规范)的一部分形如 =?A?B?C?= 的文件名是一个完全有效的文件名而不是一个不正确编码的文件名JavaMail 没有编码和解码文件名因为这样做会违反 MIME 规范
基本的 MIME 规范不允许编码参数RFC 定义了一种新的方式使得可以在 MIME 标题中包括编码参数包括文件名它与下面的事实方式不兼容许多应用程序非法编码文件名支持 RFC 将不允许 JavaMail 与这些现有的程序互操作据我所知很少现有的程序支持 RFC
如果你选择违反 MIME 规范是为了与其他也违反了 MIME的程序互操作那么 JavaMail 会给您所有需要的工具来完成这件事
编码文件名的解决方法是简单的
mbpsetFileName(MimeUtilityencodeText(filename));
解码文件名的解决方法同样简单
String filename = MimeUtilitydecodeText(partgetFi