如何在 Apache Commons Email 1.4 中接收和区分常规附件和内联附件
How to receive and distinguish between regular attachments and inline attachments in Apache Commons Email 1.4
目前我们收到一封由
解析的电子邮件
MimeMessageParser mimeMessageParser = parse(message);
然后用
取出附件
if (mimeMessageParser.hasAttachments()) {
List<DataSource> attachments = mimeMessageParser.getAttachmentList();
for (DataSource dataSource : attachments) {
saveAttachment(dataSource, subjectLineProperties, documentToUpload, firstHeaders);
}
}
问题是 getAttachmentList 也会返回内联图像,例如签名行中的企业徽标,我们不想将内联图像作为附件提取出来。我们只想要实际的电子邮件附件。附件与内联,但我们也无法通过 Apache Commons Email 1.4 版本访问 java.mail 配置,并且找不到解决方案。我查看了他们的文档 https://commons.apache.org/proper/commons-email/javadocs/api-1.4/index.html
运气不好。似乎附件 DataSource 只允许我获取内容和内容类型和名称,但如果它是内联 attachment/image 或像 Mime Parts 这样的常规附件则不行。
答案是 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;
}
我的印象是没有进入较低级别的解决方法...但我还没有检查所有附件类型 - 仅检查图像。像这样:
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
}
目前我们收到一封由
解析的电子邮件MimeMessageParser mimeMessageParser = parse(message);
然后用
取出附件 if (mimeMessageParser.hasAttachments()) {
List<DataSource> attachments = mimeMessageParser.getAttachmentList();
for (DataSource dataSource : attachments) {
saveAttachment(dataSource, subjectLineProperties, documentToUpload, firstHeaders);
}
}
问题是 getAttachmentList 也会返回内联图像,例如签名行中的企业徽标,我们不想将内联图像作为附件提取出来。我们只想要实际的电子邮件附件。附件与内联,但我们也无法通过 Apache Commons Email 1.4 版本访问 java.mail 配置,并且找不到解决方案。我查看了他们的文档 https://commons.apache.org/proper/commons-email/javadocs/api-1.4/index.html
运气不好。似乎附件 DataSource 只允许我获取内容和内容类型和名称,但如果它是内联 attachment/image 或像 Mime Parts 这样的常规附件则不行。
答案是 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;
}
我的印象是没有进入较低级别的解决方法...但我还没有检查所有附件类型 - 仅检查图像。像这样:
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
}