区分内联附件和常规附件
Contents
[
Hide
]
电子邮件可能包含内联图像以及附件。使用 MailMessage,内联附件可以从 LinkedResourceCollection 集合,而常规附件可以通过消息的 AttachmentCollection 集合中。然而,当使用…加载消息时情况不同。 MapiMessage,因为所有内联图像和常规附件对用户而言都在同一个 MapiAttachmentCollection因此,当…时,需要一种能够区分内联附件和常规附件的方法。 MapiMessage 在需要时使用。
本文解释了如何使用 … 区分内联附件和常规附件。 MapiMessage。在决策时,正文类型 MapiMessage 考虑如下:
- 纯文本正文:带有纯文本正文类型的电子邮件无需检查,因为此类消息中的所有附件始终为常规附件。
- HTML 正文:对于具有 HTML 正文的消息,附件不仅应包含 PR_ATTACH_FLAGS (0x37140003) 属性,而且其值应为 0x00000004,表示内联附件。如果满足此条件,则进一步取决于 PR_ATTACH_CONTENT_LOCATION 和 PR_ATTACH_CONTENT_ID 标记来确定附件的性质。然而,在缺少 PR_ATTACH_FLAGS MAPI 标记的情况下,附件会检查 PR_ATTACH_DISPOSITION (0x3716001F 或 0x3716001E) 属性以确定附件类型。
- RTF 正文:如果正文为 RTF,则所有 OLE 附件都是内联附件。所有 OLE 附件的 PR_ATTACH_METHOD 值等于 0x00000006。
以下代码示例演示了如何在程序中区分内联附件和常规附件。函数 isInlineAttachment 接受附件和 MapiMessage 作为输入参数,如果附件是内联附件则返回 true。
public static boolean isInlineAttachment(MapiAttachment att, MapiMessage msg) {
if (msg.getBodyType() == BodyContentType.PlainText)
// ignore indications for plain text messages
return false;
else if (msg.getBodyType() == BodyContentType.Html) {
// check the PidTagAttachFlags property
Long attachFlagsValue = att.getPropertyLong(MapiPropertyTag.PR_ATTACH_FLAGS);
if (attachFlagsValue != null && (attachFlagsValue > 3 || attachFlagsValue < 1)) {
// check PidTagAttachContentId property
String contentId = att.getProperties().containsKey(MapiPropertyTag.PR_ATTACH_CONTENT_ID)
? att.getPropertyString(MapiPropertyTag.PR_ATTACH_CONTENT_ID)
: att.getPropertyString(MapiPropertyTag.PR_ATTACH_CONTENT_ID_W);
if (contentId != null && !contentId.isEmpty() && msg.getBodyHtml().contains("cid:" + contentId)) {
return true;
}
// check PidTagAttachContentLocation property
String contentLocation = att.getProperties().containsKey(MapiPropertyTag.PR_ATTACH_CONTENT_LOCATION)
? att.getPropertyString(MapiPropertyTag.PR_ATTACH_CONTENT_LOCATION)
: att.getPropertyString(MapiPropertyTag.PR_ATTACH_CONTENT_LOCATION_W);
if (contentLocation != null && !contentLocation.isEmpty() && msg.getBodyHtml().contains(contentLocation)) {
return true;
}
}
return "inline".equals(att.getPropertyString(0x3716001F)) || "inline".equals(att.getPropertyString(0x3716001E));
} else if (msg.getBodyType() == BodyContentType.Rtf) {
// If the body is RTF, then all OLE attachments are inline attachments.
// OLE attachments have 0x00000006 for the value of the PidTagAttachMethod property
Long attachMethod = att.getPropertyLong(MapiPropertyTag.PR_ATTACH_METHOD);
return attachMethod != null && attachMethod == 0x00000006;
} else {
throw new ArgumentOutOfRangeException();
}
}
此代码片段使用 isInlineAttachment() 函数来评估附件。
Java
String fileName = ("Sample.msg");
MapiMessage message = MapiMessage.fromFile(fileName);
MapiAttachmentCollection attachments = message.getAttachments();
for (int i = 0; i < attachments.size(); i++) {
MapiAttachment attachment = (MapiAttachment) attachments.get(i);
if (isInlineAttachment(attachment, message)) {
System.out.println(attachment.getLongFileName() + " is inline attachment");
} else {
System.out.println(attachment.getLongFileName() + " is regular attachment");
}
}