You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何用Microsoft Graph API v6.16.0反序列化RFC格式.eml附件

如何使用Microsoft Graph API v6.16.0反序列化以FileAttachment形式发送的.eml文件

场景说明

.eml文件以FileAttachment形式发送,需要将其反序列化为Microsoft Graph SDK中的Message对象。

示例API响应

{
    "@odata.context": "https://graph.microsoft.com/v1.0/$metadata#users('foo%40bar.com')/messages('AAMkAGI4NjFmZjQwLTMyOWEtNDI5MS05M2JmLTZhZGY0YzM5MmM5NQBGAAAAAAAxxAUGikUbRotDsfglXTlaBwCZx2ecKdkYRqinPi0NZhdPAAAAAAEMAACZx2ecKdkYRqinPi0NZhdPAAE5suHaAAA%3D')/attachments",
    "value": [
        {
            "@odata.type": "#microsoft.graph.fileAttachment",
            "@odata.mediaContentType": "message/rfc822",
            "id": "AAMkAGI4NjFmZjQwLTMyOWEtNDI5MS05M2JmLTZhZGY0YzM5MmM5NQBGAAAAAAAxxAUGikUbRotDsfglXTlaBwCZx2ecKdkYRqinPi0NZhdPAAAAAAEMAACZx2ecKdkYRqinPi0NZhdPAAE5suHaAAABEgAQAO1R5rkS-AJDnpgFzy8Z_XI=",
            "lastModifiedDateTime": "2024-10-01T20:53:49Z",
            "name": "message.eml",
            "contentType": "message/rfc822",
            "size": 3684,
            "isInline": false,
            "contentId": null,
            "contentLocation": null,
            "contentBytes": "someRandomByte--Omitted for brevity "
        }
    ]
}

当前代码片段

private List<Message> convertAttachmentsToMessageList(List<Attachment> attachmentListPage) {
    List<Message> attachmentMessages = new ArrayList<>();
    attachmentListPage.stream().forEach(attachment -> {
        if (attachment instanceof FileAttachment) {
            FileAttachment fileAttachment = (FileAttachment) attachment;
            if (fileAttachment.getContentType().equalsIgnoreCase("message/rfc822")) {
                //TODO how do we serialize this
            }
        } else if (attachment instanceof ItemAttachment) {
            ItemAttachment itemAttachment = (ItemAttachment) attachment;
            OutlookItem item = itemAttachment.getItem();
            if (item instanceof Message) {
                attachmentMessages.add((Message) item);
            }
        }
    });
    return attachmentMessages;
}

解决方案

Microsoft Graph SDK v6.x没有内置直接解析.eml为Message对象的方法,需要借助JavaMail API完成解析并手动映射字段:

步骤1:添加JavaMail依赖

如果使用Maven,在pom.xml中添加:

<dependency>
    <groupId>com.sun.mail</groupId>
    <artifactId>jakarta.mail</artifactId>
    <version>2.0.1</version>
</dependency>

步骤2:实现反序列化逻辑

修改原有代码,添加.eml解析和转换逻辑:

import jakarta.mail.MimeMessage;
import jakarta.mail.Session;
import jakarta.mail.internet.InternetAddress;
import java.io.ByteArrayInputStream;
import java.util.Base64;
import java.util.Properties;

private List<Message> convertAttachmentsToMessageList(List<Attachment> attachmentListPage) {
    List<Message> attachmentMessages = new ArrayList<>();
    attachmentListPage.stream().forEach(attachment -> {
        if (attachment instanceof FileAttachment) {
            FileAttachment fileAttachment = (FileAttachment) attachment;
            if (fileAttachment.getContentType().equalsIgnoreCase("message/rfc822")) {
                try {
                    // 1. 解码Base64格式的.eml内容
                    byte[] emlBytes = Base64.getMimeDecoder().decode(fileAttachment.getContentBytes());
                    // 2. 用JavaMail解析成MimeMessage
                    Session session = Session.getDefaultInstance(new Properties());
                    MimeMessage mimeMessage = new MimeMessage(session, new ByteArrayInputStream(emlBytes));
                    // 3. 转换为Graph SDK的Message对象
                    Message graphMessage = mapMimeMessageToGraphMessage(mimeMessage);
                    attachmentMessages.add(graphMessage);
                } catch (Exception e) {
                    // 处理解析异常,可根据业务需求调整
                    e.printStackTrace();
                }
            }
        } else if (attachment instanceof ItemAttachment) {
            ItemAttachment itemAttachment = (ItemAttachment) attachment;
            OutlookItem item = itemAttachment.getItem();
            if (item instanceof Message) {
                attachmentMessages.add((Message) item);
            }
        }
    });
    return attachmentMessages;
}

// 手动映射MimeMessage字段到Graph的Message对象,可按需补充更多字段
private Message mapMimeMessageToGraphMessage(MimeMessage mimeMessage) throws Exception {
    Message message = new Message();
    // 设置邮件主题
    message.setSubject(mimeMessage.getSubject());
    // 设置发件人
    InternetAddress fromAddress = (InternetAddress) mimeMessage.getFrom()[0];
    message.setFrom(new Recipient()
            .emailAddress(new EmailAddress().address(fromAddress.getAddress()).name(fromAddress.getPersonal())));
    // 设置收件人(仅处理TO类型,可按需添加CC/BCC)
    InternetAddress[] toAddresses = (InternetAddress[]) mimeMessage.getRecipients(MimeMessage.RecipientType.TO);
    if (toAddresses != null) {
        message.setToRecipients(java.util.Arrays.stream(toAddresses)
                .map(addr -> new Recipient()
                        .emailAddress(new EmailAddress().address(addr.getAddress()).name(addr.getPersonal())))
                .toList());
    }
    // 设置邮件正文,支持纯文本和HTML类型
    String content = mimeMessage.getContent().toString();
    message.setBody(new ItemBody().content(content).contentType(mimeMessage.isMimeType("text/html") ? BodyType.HTML : BodyType.TEXT));
    // 设置发送时间
    message.setSentDateTime(mimeMessage.getSentDate().toInstant());
    return message;
}

关键说明

  • 使用Base64.getMimeDecoder()处理可能包含换行的标准Base64编码内容
  • mapMimeMessageToGraphMessage方法可根据业务需求补充更多字段映射(如抄送、密送、附件ID等)
  • 异常处理逻辑需结合实际场景调整,避免直接打印堆栈信息

内容的提问来源于stack exchange,提问作者Raghu Chaitanya

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.17 17:32:00