服务热线:13616026886

技术文档 欢迎使用技术文档,我们为你提供从新手到专业开发者的所有资源,你也可以通过它日益精进

位置:首页 > 技术文档 > JAVA > 新手入门 > 基础入门 > 查看文档

javamail常见问题之编程问题


  问. 从哪里可以学习有关 internet 邮件的基础知识,它是我高效编写 javamail 程序需要知道的?
  答:参见我们的 web 页中提及的 参考图书 中的一本,获得有关 internet 电子邮件、mime、smtp、imap 和 pop3 等的背景信息。
  问. 如何调试使用 javamail api 的应用程序?
  答:可通过在代码中调用 session 对象上的 setdebug(true) 方法来打开调试模式。这将造成在控制台中打印调试消息,包括协议跟踪信息。如果您认为在 javamail 中发现了 bug,就将这个跟踪及以下信息发送给我们:重生成问题的测试用例、使用的平台、使用的 jdk 的版本和使用的邮件服务器 (imap, smtp) 的名称和版本。
  问. 如何发送带有附件的消息?
  答:带有附件的消息采用 mime 多部分消息来表示,其中第一部分是消息的主体,其他的部分是附件。有大量的例子,它们展示了如何在演示程序中构建这种消息,javamail 下载包包含了这些演示程序。
  问. 如何阅读带有附件的消息并保存附件?
  答:如前面描述,在 mime 中,带有附件的消息是作为多部分消息表示的。在简单的例子中,message 对象的 getcontent 方法的结果将是一个 mimemultipart 对象。多部分对象的第一个主体部分将是消息的主文本。其他的主体部分将是附件。msgshow.java 演示程序展示了如何在消息中遍历所有的多部分对象,并提取各个主体部分数据。getdisposition 方法将给你一个提示,指出主体部分是否应该内嵌显示,或者应该将其考虑成附件(但请注意,不是所有的发件人都提供这一信息)。
  为了将主体部分中的数据保存到文件(比如),请使用 getinputstream 方法来访问附件内容,并将数据复制到 fileoutputstream。
  注意,也有一些更复杂的情形也要处理。例如,一些发件人把主体作为纯文本和 html 发送。通常,这将作为 multipart/alternative 内容(和 mimemultipart 对象)出现在简单的文本主体部分的位置中。经过数字签名或加密的消息甚至会更复杂。处理所有的这些情形可能具有挑战性。请参考各种 mime 规范和我们主页上列出的其他 参考资料。
  问. 什么是“中断支持”(disconnected support)?
  答:支持中断操作的邮件客户端将允许用户访问远程消息存储(比如 imap)中消息,缓存这些消息中的一些消息的(部分)到本地,然后断开到服务器的连接。当处在断开连接状态中,邮件客户端可以访问已经缓存的消息,可能也可以删除它们或将它们保存到其他文件夹。当邮件客户端下一次连接到远程消息存储时,本地所做变更会与远程存储同步。同样,中断支持可以允许客户端在断开与服务器连接时“发送”消息,在到服务器的连接可用前,消息会进行排队。也请参阅 rfc1733。
  问. 如何使用 javamail api 来支持中断操作?
  答:javamail api 规范定义了一些接口,邮件客户端可以使用这些接口来支持中断操作。我们的 imap 提供程序实现了这些接口(uidfolder 接口)。
  问. 我如何使用 javamail api 来发送安全的电子邮件?
  答:javamail api 目前不支持发送或接收安全电子邮件。javamail api 的体系结构使得可以在以后很容易地添加这一支持,我们可以添加支持,第三方也可以添加支持。有关当前电子邮件安全标准(s/mime 和 pgp)的信息,可以从如下站点找到: http://www.imc.org/smime-pgpmime.html。 请浏览我们的 第三方产品 页,获取来自其他供应商的解决方案。
  问. 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 提供程序,那就编写 javax.mail.store 和 javax.mail.folder的子类,也可能要编写 javax.mail.message 及其他一些类的子类。对于 transport 提供程序,编写 javax.mail.transport 的子类,也可能需要编写 javax.mail.message 及其他的一些类的子类。然后在 javamail.providers 注册表中,添加描述提供程序的条目。如果对编写特别的服务提供程序感兴趣,并且它所针对的协议或邮件系统目前没有得到 javamail api 实现的支持,请通过 javamail@sun.com 联系我们。
  问. 我在登录 microsoft exchange 服务器时碰到了麻烦,我确信正在使用的用户名和密码是正确的,我做错了什么?
  答:当登录 exchange 时,需要使用比简单登录名更多的用户名。例如,如果你的电子邮件地址是“j.user@server.com”,windows nt 登录名是“juser”,nt 域名是“dom”,而且 exahange 邮箱名是“joe user”,那么在使用 javamail 登录时,你将需要使用用户名 “dom/juser/j.user”。
  问. 在发送二进制文件前,我如何编码它?当收到它时,我又如何解码它?
  答:你不必这样的做!javamail 将自动决定合适的编码用于消息部分,然后才发送消息。而且当读取它们时,将自动解码消息部分。getinputstream 方法将返回解码数据。
  问. 如果我不需要自己编码和解码附件,我应该何时使用 mimeutility 方法?
  答:在 javamail 没有自动处理的情况下,mimeutility 方法是有用的。经常发生的这样的一种情形是文件名的编码。基本的 mime spec(规范)不允许按某种方式编码标题参数值(比如文件名参数),该方式与(比如)编码 subject(主题)标题相同。这限制了参数值,从而限制了文件名到 ascii。但一些发件人却实际使用 mime 文本编码来做非 ascii 文件名的编码工作。想与这种非标准发件人互操作的应用程序可以使用 encodetext 方法来编码文件名,然后调用 mimebodypartsetfilename 方法,而且可以使用 decodetext 方法来解码返回的文件名。
  问. 尽管 javamail 完成了所有的编码和解码工作,但我仍需要手动控制一些主体部分的编码。
  答:在少数的场合需要控制编码,这里有几个方法来重写 javamail 的默认行为。下面是一个简单的方法。在创建整个消息后,调用 msg.savechanges(),然后使用像 mbp.setheader("content-transfer-encoding", "base64") 的语句来强制对指定主体部分做 base64 编码。
  另一种办法是编写 mimebodypart 的子类,并重写 updateheaders 方法,让它首先调用 super.updateheaders(),然后像上面那样设置 content-transfer-encoding 标题。
  问. 为什么 javamail 没有在非 ascii 字符集中正确编码和解码文件名?
  答:文件名是作为参数存储在 mime 标题中的。形如 =?iso-8859-15?b?5otkluluzm8ucgrm?= 的编码文件名不是 mime spec(规范)的一部分。形如 =?a?b?c?= 的文件名是一个完全有效的文件名,而不是一个不正确编码的文件名。javamail 没有编码和解码文件名,因为这样做会违反 mime 规范。
  基本的 mime 规范不允许编码参数。rfc 2231 定义了一种新的方式,使得可以在 mime 标题中包括编码参数,包括文件名。它与下面的事实方式不兼容:许多应用程序非法编码文件名。支持 rfc 2231 将不允许 javamail 与这些现有的程序互操作。据我所知,很少现有的程序支持 rfc 2231。
  如果你选择违反 mime 规范是为了与其他也违反了 mime的程序互操作,那么 javamail 会给您所有需要的工具来完成这件事。
  编码文件名的解决方法是简单的:
  mbp.setfilename(mimeutility.encodetext(filename));
  解码文件名的解决方法同样简单:
  string filename = mimeutility.decodetext(part.getfi

扫描关注微信公众号