问 我如何回复消息?
答为了回复消息请使用 Message 对象上的 reply 方法这个方法将返回一个新的对象对象中的标题已经针对回复做了恰当设置你将需要自己提供消息的内容
问 我如何转发消息?
答用于转发消息的方法取决于你要怎样表示要转发的消息简单的办法是创建一个新的 MimeMessage并适当地为它提供地址然后将现有的消息作为附件放在新消息中为了将原始消息放在新消息中比如可以使用下面的代码
MimeBodyPart mbp = new MimeBodyPart();
mbpsetContent(forwardedMsg message/rfc);
mpaddPart(mbp);
但是如果你想创建新的消息并在新消息中包括原始消息的文本可能也要用 > 来缩进那将需要提取原始消息主体中的数据并进行相应的处理你可能也想取得原始消息的其他附件并将它们添加到新消息中
问 我如何发送 HTML 邮件?
答在分发中包括了大量演示程序它们展示了如何发送 HTML 邮件如果想发送简单消息它具有 HTML 而不是纯文本那请参见 demo(演示)目录中的 sendhtmljava 程序如果想将 HTML 文件作为附件发送请参见 sendfilejava 示例它展示了如何将任何文件作为附件发送
问 我如何发送具有不同字体和颜色的格式化文本的邮件?
答最简单的办法是使用 HTML 文本发送消息参见 上面
问 我如何发送具有纯文本和 HTML 文本的邮件让每个邮件的阅读者可以选择适合它的格式?
答你想要发送 MIME multipart/alternative 消息你构造了这样的一条消息构造方式基本上与构造 multipart/mixed 消息相同它使用了 MimeMultipart 对象而该对象又是使用 new MimeMultipart(alternative) 来构造的然后在 multipart(多部分)中把 text/plain 主体部分作为第一部分插入并且把 text/html 作为第二部分插入参阅 RFC获取这一消息的结构的细节
问 我如何发送包含图像的 HTML 邮件?
答最简单的办法是发送带有图像标签的 HTML 文本标签引用了公共 Web 站点在这种方法中在消息中并没有真正包括图像因此当用户阅读消息时如果没有连接到 Internet那将不能看到图像
另外你也可以构造 MIME multipart/related 消息参阅 RFC获取这种消息结构的细节
问 Transport 方法 send 和 sendMessage 之间有什么区别?
答send() 方法是一个静态方法可以直接使用而不需要 Transport 对象的实例它用于常见简单的场合比如使用默认传输发送单条消息从内部讲send() 方法首先调用消息上的 saveChanges() 方法然后创建合适的新 Transport 对象调用 Transport 的 connect() 方法调用 Transport 的 sendMessage() 方法来实际发送消息接着调用 Transport 的 close() 方法最后丢弃 Transport 对象的新实例并由垃圾收集器收集(实际上还有比那更加复杂的但那是一般的想法)
如你可以看到静态 send() 便利 (convenience) 方法是建立在更加通用的每实例 sendMessage() 方法的基础上的有许多原因可以让应用程序直接使用 sendMessage() 方法最常见的原因是为了通过在单个连接期间发送多条消息 来提高性能或者为了手动管理连接以提供验证信息当使用 sendMessage() 方法时产生的最常见错误是忘记在要发送的消息上调用 saveChanges() 方法
问 我需要验证到 SMTP 服务器因此我调用了 nnect(host user password)然后调用 transsend(msg) 发送消息但它却不能工作
答你应该调用 msgsaveChanges()然后调用 transsendMessage(msg addrs) 来发送消息如 上面 所描述send 方法是一个静态便利方法它会获得自己的 Transport 对象并创建自己的连接用于发送消息它没有使用与某些 Transport 对象有关的连接并且它是通过该 Transport 对象得到调用的当然不要忘记将 mailsmtpauth 属性设置为 true 来启用 SMTP 验证!
问 我修改了一条消息但标题却没有反映修改
答在创建新消息或修改现有消息后应该调用 saveChanges()这将导致重新设置标题以反映变更注意Transportsend(Message) 方法隐式调用了这个方法因此如果你正在做的是发送已修改的消息就可以跳过调用 saveChanges()saveChanges() 可能是一个昂贵的操作(特别是对于较大或深度嵌套的消息)因此只在需要时才调用它
问 我正在使用 sendMessage() 方法发送消息但在消息中的文本前后却出现奇怪的一些行并且我的附件也在消息体中出现
答通常这些行像下面这样
JavaMailname@host
像 上面 那样在创建新消息后在使用 TransportsendMessage() 方法发送消息之前必须调用 saveChanges() 方法静态 Transportsend() 方法将自动调用 MessagesaveChanges() 方法
问 我为新消息的 MessageID 标题设置了特定值但当我发送这条消息时却重写了那个标题
答saveChanges() 将为 MessageID 字段设置新值重写所设置的任何值如果需要设置自己的 MessageID 并保留它就必须创建自己的 MimeMessage 子类重写 updateHeaders() 方法并使用这个子类的一个实例
class MyMessage extends MimeMessage {
protected void updateHeaders() throws MessagingException {
superupdateHeaders();
setHeader(MessageID mymessageid);
}
}
问 当发送创建的新消息时为什么会得到 UnsupportedDataTypeException?
答你可能使用 setContent(Object o String type) 方法设置了消息的一些内容为了让它能工作必须为指定类型注册 JAF DataContentHandler如果不这样做将获得 UnsupportedDataTypeException参阅 JAF 文档获取进一步信息
问 当发送消息时如何能够显式地设置 SMTP FROM: 属性?
答mailsmtpfrom 属性可用于设置 SMTP FROM: 属性如果没有设置这个属性就使用消息的 From 属性如果多个线程需要同时发送邮件并且每个线程需要设置 From 属性那么每个线程就必须使用自己的 Session 对象它具有自己的 Properties 对象然后可以在每个 Session 对象的 各个 Properties 对象上独立设置 mailsmtpfrom 属性(同样对每个线程做这样的设置)
问 我想重复发送消息并且每次发送给一组不同的收件人但调用 Transportsend(Message) 却导致每次都创建一个新的 Transport 会话在本例中这是一个次优办法我如何来解决它?
答创建合适的 Transport 对象的实例然后连上它并重复调用 sendMessage() 方法例如
MimeMessage msg = ;
// construct message
msgsaveChanges();
Transport t = sessiongetTransport(smtp);
nnect();
for (int i = ; ) {
tsendMessage(msg new Address[] { recipients[i] });
}
tclose();
问 当试图发送消息时我得到了 MessagingException: HELO requires domain address(MessagingException: HELO 要求域地址)
答在 SMTP HELO 命令中SMTP 提供程序使用 InetAddressgetLocalHost()getHostName() 的结果如果那个调用不能返回任何数据就不会在 HELO 命令中发送任何名称检查你的 JDK 和名称服务器配置确保那个调用返回正确数据从 JavaMail 开始你也可以设置 mailsmtplocalhost 属性并可以把设置为想用于 HELO 命令的名称
问 如果将消息发送到错误的地址为什么我会获得 SendFailedException 或 TransportEvent指出地址是错误的?
答在 Internet 上没有端到端验证通常要将消息转发到几个邮件服务器然后才到达特定的邮件服务器该服务器决定了它是否可以传送消息如果在这些后面的步骤中的某个步骤发生了错误那么通常会将消息作为不可传送返回给发件人一个成功的发送只表明邮件服务器已经接受了消息并将试着传送它
问 当消息不能被传送时就会返回一个失败消息我如何检测这些回弹消息?
答虽然有一个 Internet 标准用于报告这样的错误(multipart/report MIME 类型参阅 RFC)但还没有广泛实现它RFC 深入讨论了这个问题包括了大量的例子
在 Internet 电子邮件中特定的邮箱或用户名是否存在只能由传送消息的最终服务器决定消息可能通过几个中继服务器(它们不能检测错误)然后再到达最终服务器通常当最终服务器检测到这一错误它会返回一个消息给原始消息的发送人指出失败的原因有许多 Internet 标准讨论了这种传送状态通知 (Delivery Status Notifications)但大量服务器不支持这些新标准相反使用特别技术来返回这种错误消息这使得将回弹消息与产生问题的原始消息相互关联起来非常困难(注意这个问题与 JavaMail 完全无关)
有许多技术和试探法用于处理这一问题但它们都不是完美的一种技术是 Variable Envelope Return Paths 描述了这一技术
问 当创建 InternetAddress 对象时如果地址是非法的为什么不会获得异常?
答InternetAddress 类只检查地址的语法如 上面 所讨论InternetAddress 类不能决定地址是否做为合法地址实际存在如果应用程序运行在防火墙背后或目前没有连接到 Internet那么甚至不能验证主机名
问 当试图发送消息时我为什