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

使用JavaMail 1.5.6解析嵌套EML文件时内容为空问题咨询

解决JavaMail 1.5.6解析内嵌EML附件返回null的问题

我刚碰到一模一样的问题!之前用JavaMail 1.5.6写EML解析器,参考官方msghow.java示例,结果遇到带EML附件的邮件时,明明能识别出这个附件是message/rfc822类型,但调用getSubject()、getSentDate()这些方法全返回null,连正文都拿不到。之前用mime4j没问题,但就想纯用JavaMail搞定,后来终于找到原因了。

先看看你提供的测试邮件片段:

MIME-Version: 1.0
Date: Tue, 30 Apr 2019 16:20:45 +0200
Message-ID: <CA+fLqEW8TUfSxih9DTp2WXa63pS7wf1eZiro_9k1XS4AShN5Zg@mail.gmail.com>
Subject: Message with an eml as attachment
From: a b <ab@gmail.com>
To: cd@pec.cd.it
Content-Type: multipart/mixed; boundary="00000000000057f76c0587c01bc9"
--00000000000057f76c0587c01bc9
Content-Type: multipart/alternative; boundary="00000000000057f7670587c01bc7"
--00000000000057f7670587c01bc7
Content-Type: text/plain; charset="UTF-8"
Hello guys, this is a simple message from a not certified account, it contains only one attachment, an eml message
--00000000000057f7670587c01bc7
Content-Type: text/html; charset="UTF-8"
<div dir="ltr">Hello guys,<div><br></div><div>this is a simple message from a not certified account, it contains only one attachment, an eml message</div></div>
--00000000000057f76c0587c01bc9
Content-Type: message/rfc822; name="Cena zerebao.eml"
Content-Disposition: attachment; filename="Cena zerebao.eml"
Content-Transfer-Encoding: base64
X-Attachment-Id: f_jv3vpu760
Content-ID: <f_jv3vpu760>
WC1Ob3Rlcy1JdGVtOiBGcmksIDYgSnVsIDIwMTggMTc6NDA6MDAgKzAyMDA7DQogdHlwZT00MDA7 IG5hbWU9T3JpZ2luYWxNb2RUaW1lDQpYLU5vdGVzLUl0ZW06IE1lbW87DQogbmFtZT1Gb3JtDQpY LU5vdGVzLUl0ZW06IFN0ZE5vdGVzTHRyMjU7DQo.... and so on

问题根源

官方的msghow.java示例没有专门处理message/rfc822类型的附件,它只是把所有BodyPart当成普通附件或文本内容来处理,但实际上这种类型的附件本身就是一封完整的邮件,不能直接用MimeBodyPart的方法去获取邮件头信息,必须把它转换成MimeMessage对象才行。

解决方法

遍历父邮件的Multipart内容时,一旦检测到BodyPart是message/rfc822类型,就用它的输入流创建一个新的MimeMessage实例,之后就能像处理普通邮件一样获取它的主题、日期、正文和附件了。

给你一段核心代码示例:

// 假设已经获取到父邮件的MimeMessage对象message
Multipart multipart = (Multipart) message.getContent();
Session session = Session.getDefaultInstance(new Properties());

for (int i = 0; i < multipart.getCount(); i++) {
    BodyPart bodyPart = multipart.getBodyPart(i);
    
    if (bodyPart.isMimeType("message/rfc822")) {
        // 关键步骤:将EML附件转换为MimeMessage
        MimeMessage nestedMessage = new MimeMessage(session, bodyPart.getInputStream());
        
        // 现在可以正常获取内嵌EML的各种信息了
        String nestedSubject = nestedMessage.getSubject();
        Date nestedSentDate = nestedMessage.getSentDate();
        Object nestedContent = nestedMessage.getContent();
        
        // 递归解析内嵌EML的内容和附件(如果有的话)
        parseEmailContent(nestedMessage); // parseEmailContent是你自己实现的解析方法
    } else {
        // 处理普通文本内容或非EML附件
        if (Part.ATTACHMENT.equalsIgnoreCase(bodyPart.getDisposition())) {
            // 处理普通附件
            String fileName = bodyPart.getFileName();
            // ...
        } else {
            // 处理正文文本
            String content = bodyPart.getContent().toString();
            // ...
        }
    }
}

为什么这样可行?

message/rfc822类型的附件本质上是符合RFC822标准的邮件内容,JavaMail的MimeMessage正好是用来解析这种格式的。通过输入流重新构建MimeMessage,就能让JavaMail正确解析它的邮件头和内容结构,而不是把它当成一段二进制或文本数据。

之前我就是这么改的,改完之后内嵌EML的所有信息都能正常获取了,官方示例msghow.java也可以按这个逻辑修改来解决问题。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.13 07:24:57