Reputation: 417
I want to extract ALL the attachments of an .eml message which is encapsulated (Content-Type: message/rfc822) in the message InputStream
InputStream is = new FileInputStream(Path);
MimeMessage mime = new MimeMessage(null, is);
private String getAttachments(p) throws
MessagingException, IOException {
if ( p.isMimeType("multipart/*")) {
Multipart multiPart = (Multipart) p.getContent();
int numberOfParts = multiPart.getCount();
for (int partCount = 0; partCount < numberOfParts; partCount++) {
MimeBodyPart part = (MimeBodyPart) multiPart.getBodyPart(partCount);
String disp = part.getDisposition();
if (disp != null && disp.equalsIgnoreCase(Part.ATTACHMENT) {
file_name = part.getFileName();
part.saveFile(Attachments_Folder + "\\" + MailFileName + "_" + file_name);
}
}
}
}
is.close()
Also, when the Content-Type is message/rfc822, the part.getFileName() is null and therefore the saved file has no extension and I don't know how to get this one.
Upvotes: 2
Views: 4225
Reputation: 399
Better use org.apache.commons.mail.util.MimeMessageParser.
MimeMessageParser
has as method called hasAttachments()
which
returns true
, if message has an attachments.
Then loop through the all attachments and check for content-type
message/rfc822
from getContentType()
.
DataSource InputStream
final MimeMessage message = new MimeMessage(null,attachment.getInputStream());
<dependency>
<groupId>org.apache.commons</groupId>
<artifactId>commons-email</artifactId>
<version>RELEASE</version>
</dependency>
public void readEmails() throws Exception{
// mail server connection parameters
String host = "host";
String user = "username";
String pwd = "pwd";
// connect to my pop3 inbox
Properties properties = System.getProperties();
Session session = Session.getDefaultInstance(properties);
Store store = session.getStore("pop3");
store.connect(host, user, pwd);
Folder inbox = store.getFolder("INBOX");
inbox.open(Folder.READ_ONLY);
// get the list of inbox messages
Message[] messages = inbox.getMessages();
if (messages.length == 0) System.out.println("No messages found.");
for (int i = 0; i < messages.length; i++) {
// stop after listing ten messages
if (i > 10) {
System.exit(0);
inbox.close(true);
store.close();
}
final MimeMessageParser mimeMessageParser = new MimeMessageParser((MimeMessage) messages[i]);
mimeMessageParser.parse();
if (mimeMessageParser.hasAttachments()) {
List<DataSource> attachmentList = mimeMessageParser.getAttachmentList();
System.out.println("Number of attachments: " +attachmentList.size());
for (DataSource attachment:attachmentList
) {
System.out.println("Name: "+attachment.getName()+" Content Type: "+attachment.getContentType());
if (attachment.getContentType().equals("message/rfc822")) {
final MimeMessage message = new MimeMessage(null,attachment.getInputStream());
System.out.println("Subject of the attached failure Mail:" + message.getSubject());
}
}
}
System.out.println("Message " + (i + 1));
System.out.println("From : " + messages[i].getFrom()[0]);
System.out.println("Subject : " + messages[i].getSubject());
System.out.println("Sent Date : " + messages[i].getSentDate());
System.out.println();
}
inbox.close(true);
store.close();
}
Upvotes: 1
Reputation: 417
I did it by adding a new filename to the included message as an .eml file and a recursion with the included message
import java.util.*;
import javax.activation.DataHandler;
import javax.mail.*;
import javax.mail.internet.*;
import javax.mail.search.*;
import java.io.FileInputStream.*;
import javax.mail.internet.MimeMessage;
import javax.mail.internet.MimeBodyPart;
import javax.mail.Part;
import javax.mail.Multipart;
getAttachments(Path) ;
//function
private String getAttachments(path) throws
MessagingException, IOException {
InputStream is = new FileInputStream(path);
MimeMessage p = new MimeMessage(null, is);
if ( p.isMimeType("multipart/*")) {
// if (contentType.contains("multipart")) {
Multipart multiPart = (Multipart) p.getContent();
int numberOfParts = multiPart.getCount();
for (int partCount = 0; partCount < numberOfParts; partCount++) {
MimeBodyPart part = (MimeBodyPart)multiPart.getBodyPart(partCount);
String disp = part.getDisposition();
if (disp != null && disp.equalsIgnoreCase(Part.ATTACHMENT)) {
file_name = part.contentType == "message/rfc822" ? "message_inclus" + partCount + ".eml" : MimeUtility.decodeText(part.getFileName());
exportedpath = Attachments_Folder + "/" + MailFileName + "_" + file_name;
part.saveFile(exportedpath);
if ( part.contentType == "message/rfc822" ) {
getAttachments(exportedpath)
}
}
}
}
is.close()
return 1
}
Upvotes: 2
Reputation: 29971
MIME does not require every body part to have a file name. If the part doesn't have a file name and you need one, you'll have to make one up yourself.
Note also that you want to be very careful when using a file name that you get in an email message. It could be something unexpected or malicious, e.g., containing "../../../../../whatever".
Upvotes: 1