如何在Apache Commons Email 1.4中接收和区分常规附件和内联附件

时间:2018-09-17 18:00:43

标签: apache-commons-email

当前,我们收到一封由

解析的电子邮件
MimeMessageParser mimeMessageParser = parse(message);

,然后用

拉出附件
 if (mimeMessageParser.hasAttachments()) {
     List<DataSource> attachments = mimeMessageParser.getAttachmentList();
     for (DataSource dataSource : attachments) {
         saveAttachment(dataSource, subjectLineProperties, documentToUpload, firstHeaders);
     }
 }

问题在于,getAttachmentList还会返回内嵌图像,例如在企业徽标的签名行中,并且我们不想提取内嵌图像作为附件。我们只需要实际的电子邮件附件。 ATTACHMENT与INLINE,但是我们也无法通过Apache Commons Email 1.4版本访问java.mail处置,也找不到解决方案。我检查了他们的文档https://commons.apache.org/proper/commons-email/javadocs/api-1.4/index.html

没有运气。看来附件数据源仅允许我获取内容以及内容类型和名称,但是如果它是嵌入式附件/图像或像Mime Parts那样的常规附件,则不允许。

2 个答案:

答案 0 :(得分:0)

答案是Apache Commons Email无法做到这一点。为了做出这些区别,您必须走到较低的层次并在JDK中编码老式的MimeMessage和MultiPart类。

因此来自mimeMessageParser.getAttachmentList();打电话给我们

        if (mimeMessageParser.hasAttachments()) {
            final Multipart mp = (Multipart) message.getContent();
            if (mp != null) {
                List<DataSource> attachments = extractAttachment(mp);
                for (DataSource dataSource : attachments) {
                    saveAttachment(dataSource, subjectLineProperties, documentToUpload, firstHeaders);
                }
            }
        }


private static List<DataSource> extractAttachment(Multipart multipart) {
    List<DataSource> attachments = new ArrayList<>();
    try {

        for (int i = 0; i < multipart.getCount(); i++) {
            BodyPart bodyPart = multipart.getBodyPart(i);

            if (bodyPart.getContent() instanceof Multipart) {
                // part-within-a-part, do some recursion...
                extractAttachment((Multipart) bodyPart.getContent());
            }

            System.out.println("bodyPart.getDisposition(): " + bodyPart.getDisposition());
            if (!Part.ATTACHMENT.equalsIgnoreCase(bodyPart.getDisposition())) {
                continue; // dealing with attachments only
            }

            InputStream is = bodyPart.getInputStream();
            String fileName = bodyPart.getFileName();
            String contentType = bodyPart.getContentType();
            ByteArrayDataSource dataSource = new ByteArrayDataSource(is, contentType);
            dataSource.setName(fileName);
            attachments.add(dataSource);
        }
    } catch (IOException | MessagingException e) {
        // TODO Auto-generated catch block
        e.printStackTrace();
    }
    return attachments;
}

答案 1 :(得分:0)

给我的印象是,有一种解决方法无需深入探讨……但是我还没有检查所有附件类型-仅针对图像。像这样:

for(DataSource ds : mimeMessageParser.getAttachmentList()) {
    for(String id : mimeMessageParser.getContentIds()) {
        if(ds == mimeMessageParser.findAttachmentByCid(id)) {
            // It is inline attachment with Content ID
            break;
        }
    }
    // If not found - it is file attachment without content ID
}