How to get filename of all attachements of email? - java

I am trying to get the filename of all the attachements of emails using java and imap.My code is:
MimeMessage msg = (MimeMessage) messages[i];
String fileName = msg.getFileName();
System.out.println("The file name of this attachment is " + fileName);
but it prints null always even if email contain attachment..I have seen different codes on SO but none worked...and I don't know what to do if attachment is more than one .
PS:I only want to get the filename and don't want to download attachments.

First, to determine if a message may contain attachments using the following code:
// suppose 'message' is an object of type Message
String contentType = message.getContentType();
if (contentType.contains("multipart")) {
// this message may contain attachment
}
Then we must iterate through each part in the multipart to identify which part contains the attachment, as follows:
Multipart multiPart = (Multipart) message.getContent();
for (int i = 0; i < multiPart.getCount(); i++) {
MimeBodyPart part = (MimeBodyPart) multiPart.getBodyPart(i);
if (Part.ATTACHMENT.equalsIgnoreCase(part.getDisposition())) {
// this part is attachment
// code to save attachment...
}
}
And to save the file, you could do:
part.saveFile("D:/Attachment/" + part.getFileName());
Source

there is an easier way with apache commons mail:
final MimeMessageParser mimeParser = new MimeMessageParser(mimeMessage).parse();
final List<DataSource> attachmentList = mimeParser.getAttachmentList();
for (DataSource dataSource: attachmentList) {
final String fileName = dataSource.getName();
System.out.println("filename: " + fileName);
}

I was facing the same issue when the email contained another email as an attachment. The content-disposition of such an attachment does not contain fileName.
String contentType = message.getContentType();
List<String> attachmentFiles = new ArrayList<String>();
if(contentType.contains("multipart"))
{
Multipart multiPart = (Multipart)message.getContent();
int numberOfParts = multiPart.getCount();
for(int partCount = 0; partCount < numberOfParts; partCount++)
{
MimeBodyPart part = (MimeBodyPart)multiPart.getBodyPart(partCount);
if(Part.ATTACHMENT.equalsIgnoreCase(part.getDisposition())) {
String fileName = part.getFileName();
String extension = FilenameUtils.getExtension(fileName);
//If the attachment is an email, fileName will be null.
if ("message/rfc822".equalsIgnoreCase(part.getContentType())) {
MimeMessage tempMessage = new MimeMessage(null, part.getInputStream());
fileName = tempMessage.getSubject()+".eml"; //all the email attachments will be converted to .eml format.
extension = "eml";
}
File tempEmailFile = File.createTempFile(messageId + "_" + partCount , "." + extension);
part.saveFile(tempEmailFile);
attachmentFiles.add(fileName);
attachmentFiles.add(tempEmailFile.getAbsolutePath());
}
}
}
Reference: javamail also extract attachments of encapsulated message Content-Type: message/rfc822

Related

Javamail Getting one extra file On downloading attachments

I'm getting one extra file of type File on downloading attachments. I'm using MimeBodyPart.saveFile() here is my download attachment code
for (MimeBodyPart mbp : msgToDownload.getAttachmentList()) {
updateProgress(msgToDownload.getAttachmentList().indexOf(mbp),
msgToDownload.getAttachmentList().size());
mbp.saveFile(DOWNLOAD_LOCATION + mbp.getFileName());
}
here msgToDownload is a Class that take Message msg as parameter with some other parameters. And getAttachmentList() is a list of type MimeBodyPart defined as List<MimeBodyPart>
This is how I'm adding attachments to list
sb.setLength(0);
msgToRender.clearAttachments();
Message msg = msgToRender.getMsgRef();
try {
// String messageType = msg.getContentType();
sb.append(getText(msg));
if (hasAttachments(msg)) {
Multipart mp = (Multipart) msg.getContent();
for (int i = mp.getCount() - 1; i >= 0; i--) {
BodyPart bp = mp.getBodyPart(i);
MimeBodyPart mbp = (MimeBodyPart) bp;
msgToRender.addAttachment(mbp);
}
}
}catch(Exception e){
}
Extra file contain attributes of text part of the Mail. Content of extra file
-001a114fd0aa0b377d0546bb84a0 Content-Type: text/plain; charset=UTF-8 please find the attachments... --001a114fd0aa0b377d0546bb84a0 Content-Type: text/html; charset=UTF-8 please find the attachments... --001a114fd0aa0b377d0546bb84a0--
First, you should learn about the isMimeType method.
The problem is most likely that you're not handling multipart/alternative messages. See the sample code in the JavaMail FAQ.

Can't read attachment from iphone when using Javamail to attach inline image

Attachments appear well except on iphone when I add an image as MimeBodyPart.INLINE , what is the best way to attach an image as signature using javamail?
If I remove "imagePart", all other attachments work well
I used :
MimeMessage m = new MimeMessage(session);
MimeMultipart content = new MimeMultipart("related");
// ContentID is used by both parts
String cid = ContentIdGenerator.getContentId();
// HTML part
String textPartSaine = Tools.convertSymbolToUTF8(emailContenu, true);
MimeBodyPart textPart = new MimeBodyPart();
textPart.setText("<html><head>"
+ "<title></title>"
+ "</head>\n"
+ "<body>"
+ "<div>"+ textPartSaine.replaceAll("\n", "<BR/>") +"</div><BR/><BR/>"
+ "<div><img src=\"cid:"
+ cid
+ "\" /></div><BR/><BR/>" + "</body></html>",
"US-ASCII", "html");
content.addBodyPart(textPart);
// Image part
if(signature != null && signature.exists()){
MimeBodyPart imagePart = new MimeBodyPart();
imagePart.attachFile(signature);
imagePart.setContentID("<" + cid + ">");
imagePart.setDisposition(MimeBodyPart.INLINE);
content.addBodyPart(imagePart);
}
if(fichiers != null && fichiers.length > 0) {
for(i = 0; i < fichiers.length; i++) {
partie = new MimeBodyPart();
partie.attachFile(fichiers[i]);
content.addBodyPart(partie);
}
}
Thanks
Solved
multipart/mixed (Will contain text and attachments)
multipart/alternative (Will contain text and HTML)
multipart/related (HTML + embedded images)
image1 (Content-Id: xxx)
image2
...
attachment 1
attachment 2
...

Extracting PST file containing mail as an attachment of PSTMessage

I'm trying to extract PST files using java-libpst-0.8.1 , following
https://code.google.com/p/java-libpst/
In my sample pst file, there are several mails. In one of the mail of that pst file, the attachment is also a mail. While parsing that PSTMessage, it's not able to fetch even, attachment's name. Please find the sample code.
PSTMessage email;
PSTAttachment attach;
email = (PSTMessage) folder.getNextChild();
while (email != null) {
try {
numberOfAttachments = email.getNumberOfAttachments();
if (numberOfAttachments > 0) {
for (int x = 0; x < numberOfAttachments; x++) {
attach = email.getAttachment(x);
try {
attachmentName = attach.getLongFilename();
Though the program is giving the exact count of the mail's attachments. But it's not able to provide, the attached mail's name or extracting it's content. Can anyone suggest a way what should I do?
Finally, I'm able to read the mail which is an attachment of a mail. There is a method getEmbeddedPSTMessage() in PSTAttachment class. First I need to check whether it's a normal attachment or a mail. For that we need to refer getAttachMethod(). If it returns 5 it's an embedded message. For details, please check out the documentation of PSTAttachment.
if (attach.getAttachMethod() == 5) {
PSTMessage attachEmail = attach.getEmbeddedPSTMessage();
}
Have you tried to convert the EmbeddedPSTMessage into actual .msg format?
I am using the the library to read the pst file and the second process is I am converting the PSTMessage into javax.mail.internet.MimeMessage and save it as .eml.
The problem I have now is that whenever the attachment is embedded message (.msg format), it is getting converted to .dat extension.
Would you know how to convert the EmbeddedPSTMessage and attach it as the original msg format?
Im really desperate right now.
Below are the codes snippet:
// saving as .eml
MimeMessage mimeMessage = convertToMimeMessage(email);
fileName = getRidOfIllegalFileNameCharacters(email.getSubject());
File emlFile = new File("C:\\eml\\" + fileName + ".eml");
emlFile.createNewFile();
mimeMessage.writeTo(new FileOutputStream(emlFile));
private static MimeMessage convertToMimeMessage(PSTMessage email) throws MessagingException, IOException, PSTException {
Properties p = System.getProperties();
Session session = Session.getInstance(p);
MimeMessage mimeMessage = new MimeMessage(session);
//attachment part
MimeMultipart rootMultipart = new MimeMultipart();
for (int i = 0; i < email.getNumberOfAttachments(); i++) {
PSTAttachment attachment = email.getAttachment(i);
if (attachment != null && attachment.getFileInputStream() != null) {
MimeBodyPart attachmentBodyPart = new MimeBodyPart();
if (attachment.getMimeTag() != null && attachment.getMimeTag().length() > 0) {
DataSource source = new ByteArrayDataSource(attachment.getFileInputStream(), attachment.getMimeTag());
attachmentBodyPart.setDataHandler(new DataHandler(source));
} else {
DataSource source = new ByteArrayDataSource(attachment.getFileInputStream(), "application/octet-stream");
attachmentBodyPart.setDataHandler(new DataHandler(source));
}
attachmentBodyPart.setContentID(attachment.getContentId());
String fileName = "";
if (attachment.getLongFilename() != null && attachment.getLongFilename().length() > 0) {
fileName = attachment.getLongFilename();
} else if (attachment.getDisplayName() != null && attachment.getDisplayName().length() > 0) {
fileName = attachment.getDisplayName();
} else if (attachment.getFilename() != null && attachment.getFilename().length() > 0) {
fileName = attachment.getFilename();
}
attachmentBodyPart.setFileName(fileName);
rootMultipart.addBodyPart(attachmentBodyPart);
}
}
mimeMessage.setContent(rootMultipart);
return mimeMessage;
JPST exports embedded messages as attachments in the original .msg file format. As I remember they have method in the Attachment object to identify if attachment is embedded message.
JPST is another library, not free one you use, but worth to try.
Example:
for (Attachment attachment : message.getAttachments()) {
Message embeddedMessage = attachment.getEmbeddedMessage();
if (embeddedMessage != null) {
embeddedMessage.setEmbedded(false); //Important
embeddedMessage.save("e:\\testfolder\\" +
getFileName(attachment.getDisplayName()) + ".msg");
} else {
attachment.save("e:\\testfolder\\" + attachment.getFileName());
}
}

Javamail Parsing Email Body with 7BIT Content-Transfer-Encoding

I've been implementing an feature to read email file. If the file have attachment, return attachment name.
Now I'm using Javamail library to parse email file. Here is my code.
public static void parse(File file) throws Exception {
InputStream source = new FileInputStream(file);
MimeMessage message = new MimeMessage(null, source);
Multipart multipart = (Multipart) message.getContent();
for (int i = 0; i < multipart.getCount(); i++) {
BodyPart bodyPart = multipart.getBodyPart(i);
String disposition = bodyPart.getDisposition();
if (disposition != null
&& disposition.equalsIgnoreCase(Part.ATTACHMENT)) {
System.out.println("FileName:"
+ MimeUtility.decodeText(bodyPart.getFileName()));
}
}
}
It works fine but when email file have 7bit Content-Transfer-Encoding, bodyPart.getFileName() make NullPointerException.
Is there any way to get attachement name when email is 7bit Content-Transfer-Encoding?
Sorry for my poor English.
Edited: Here is some info about my test file.
(X-Mailer: Mew version 2.2 on Emacs 21.3 / Mule 5.0 (SAKAKI)); (Mime-Version:1.0):(Content-Type: Multipart/Mixed); (Content-Transfer-Encoding: 7bit)
If my answer does not work, show the stack trace.
Use a Session, as that probably is the only thing being null.
Properties properties = new Properties();
Session session = Session.getDefaultInstance(properties);
MimeMessage message = new MimeMessage(session, source);
Not all attachments have a filename. You need to handle that case.
And you don't need to decode the filename.
You can handle the case of "attachments not having a name" in this way:
String fileName = (bodyPart.getFileName() == null) ? "your_filename"
: bodyPart.getFileName();

Reading mails sent from GMail

I am using JavaMail to read mail in my Android app. I have tried to cover all combinations i.e Mail sent/received on/from Custom Server/Gmail ID/Live ID.
The problem occurs with SOME of the mails sent from GMail WITH Attachment. I am able to receive the attachment, but the content returns javax.mail.internet.MimeMultipart#44f2e698
Here's the code used to receive and read messages:
Properties props = System.getProperties();
props.setProperty("mail.store.protocol", "imap");
try {
/* Create the session and get the store for read the mail. */
Session session = Session.getInstance(props, null);
Store store = session.getStore("imaps");
store.connect("imap.gmail.com", Username, Password);
/* Mention the folder name which you want to read. */
Folder inbox = store.getFolder("INBOX");
System.out.println("No of Unread Messages : " + inbox.getUnreadMessageCount());
/* Open the inbox using store. */
inbox.open(Folder.READ_ONLY);
Message messages[] = inbox.getMessages();
Log.d("Inbox", "Message Count: "+inbox.getMessageCount());
for (int i = messages.length - 1 ; i > 0; --i) {
Log.i("ContentType", "ContentType: "+messages[i].getContentType());
Object msgContent = messages[i].getContent();
String content = "";
/* Check if content is pure text/html or in parts */
if (msgContent instanceof Multipart) {
Multipart multipart = (Multipart) msgContent;
Log.e("BodyPart", "MultiPartCount: "+multipart.getCount());
for (int j = 0; j < multipart.getCount(); j++) {
BodyPart bodyPart = multipart.getBodyPart(j);
String disposition = bodyPart.getDisposition();
if (disposition != null && (disposition.equalsIgnoreCase("ATTACHMENT"))) { // BodyPart.ATTACHMENT doesn't work for gmail
System.out.println("Mail have some attachment");
DataHandler handler = bodyPart.getDataHandler();
System.out.println("file name : " + handler.getName());
}
else {
System.out.println("Content: "+bodyPart.getContent());
content= bodyPart.getContent().toString();
}
}
}
else
content= messages[i].getContent().toString();
What I know about the problematic mails:
getFrom also return the name i.e it comes in this format FirstName LastName &ltemailID#gmail.com&gt
MultiPart contains 2 BodyParts:
BodyPart 1 returns the content as javax.mail.internet.MimeMultipart#44f2e698
BodyPart 2 returns the correct name for attachment
BodyPart 1 returns the content as
javax.mail.internet.MimeMultipart#44f2e698
Try calling getBodyPart on the MimeMultiPart
That probably returns a MimeBodyPart you can call getContent() on
http://docs.oracle.com/javaee/5/api/javax/mail/internet/MimeBodyPart.html#content
You're probably only handling the simplest case of a text message with attachments. MIME allows much more. You need to learn about the difference between multipart/mixed, multipart/alternative, multipart/related, and multipart/signed. The JavaMail FAQ has more information on handling attachments and the msgshow.java demo program included with the JavaMail download bundle shows how to process messages with nested multiparts.

Categories