如何用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
相关产品推荐
相关产品推荐

