In this tutorial, I will guide you how to write Java code to download attachments from emails programmatically, using JavaMail API.

The article Receive e-mail messages from a POP3-IMAP server describes necessary steps to download e-mail messages from mail server, but only basic information of a message is retrieved, such as header fields (from, to, cc, subject…) and body message. However, the attachment is skipped. So this article is a complement which focuses on how to download attachments in an e-mail message.

A message may contain one or several attachments. As discussed in the article Send e-mail with attachment in Java, if a message contains attachments, its content must be of type MultiPart, and the part contains a file must be of type MimeBodyPart. So it’s important 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...
	}
}

The MimeBodyPart class provides methods for retrieving and storing attached file, but the way is different between JavaMail 1.3 and JavaMail 1.4.

In JavaMail 1.3, we have to read bytes from an InputStream which can be obtained from the method getInputStream() of the class MimeBodyPart, and write those bytes into an OutputStream, for example:

// save an attachment from a MimeBodyPart to a file
String destFilePath = "D:/Attachment/" + part.getFileName();

FileOutputStream output = new FileOutputStream(destFilePath);

InputStream input = part.getInputStream();

byte[] buffer = new byte[4096];

int byteRead;

while ((byteRead = input.read(buffer)) != -1) {
	output.write(buffer, 0, byteRead);
}
output.close(); 

In JavaMail 1.4, the MimeBodyPart class introduces two convenient methods that save us a lot of time:

-          void saveFile(File file)

-          void saveFile(String file)

So saving attachment from a part to a file is as easy as:

part.saveFile("D:/Attachment/" + part.getFileName());

 

or:

part.saveFile(new File(part.getFileName()));

 

And following is code of sample program that connects to a mail server via POP3 protocol, downloads new messages and save attachments to files on disk, if any. And it follows JavaMail 1.4 approach:

package net.codejava.mail;

import java.io.File;
import java.io.IOException;
import java.util.Properties;

import javax.mail.Address;
import javax.mail.Folder;
import javax.mail.Message;
import javax.mail.MessagingException;
import javax.mail.Multipart;
import javax.mail.NoSuchProviderException;
import javax.mail.Part;
import javax.mail.Session;
import javax.mail.Store;
import javax.mail.internet.MimeBodyPart;

/**
 * This program demonstrates how to download e-mail messages and save
 * attachments into files on disk.
 *
 * @author www.codejava.net
 *
 */
public class EmailAttachmentReceiver {
	private String saveDirectory;

	/**
	 * Sets the directory where attached files will be stored.
	 * @param dir absolute path of the directory
	 */
	public void setSaveDirectory(String dir) {
		this.saveDirectory = dir;
	}

	/**
	 * Downloads new messages and saves attachments to disk if any.
	 * @param host
	 * @param port
	 * @param userName
	 * @param password
	 */
	public void downloadEmailAttachments(String host, String port,
			String userName, String password) {
		Properties properties = new Properties();

		// server setting
		properties.put("mail.pop3.host", host);
		properties.put("mail.pop3.port", port);

		// SSL setting
		properties.setProperty("mail.pop3.socketFactory.class",
				"javax.net.ssl.SSLSocketFactory");
		properties.setProperty("mail.pop3.socketFactory.fallback", "false");
		properties.setProperty("mail.pop3.socketFactory.port",
				String.valueOf(port));

		Session session = Session.getDefaultInstance(properties);

		try {
			// connects to the message store
			Store store = session.getStore("pop3");
			store.connect(userName, password);

			// opens the inbox folder
			Folder folderInbox = store.getFolder("INBOX");
			folderInbox.open(Folder.READ_ONLY);

			// fetches new messages from server
			Message[] arrayMessages = folderInbox.getMessages();

			for (int i = 0; i < arrayMessages.length; i++) {
				Message message = arrayMessages[i];
				Address[] fromAddress = message.getFrom();
				String from = fromAddress[0].toString();
				String subject = message.getSubject();
				String sentDate = message.getSentDate().toString();

				String contentType = message.getContentType();
				String messageContent = "";

				// store attachment file name, separated by comma
				String attachFiles = "";

				if (contentType.contains("multipart")) {
					// content may contain attachments
					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())) {
							// this part is attachment
							String fileName = part.getFileName();
							attachFiles += fileName + ", ";
							part.saveFile(saveDirectory + File.separator + fileName);
						} else {
							// this part may be the message content
							messageContent = part.getContent().toString();
						}
					}

					if (attachFiles.length() > 1) {
						attachFiles = attachFiles.substring(0, attachFiles.length() - 2);
					}
				} else if (contentType.contains("text/plain")
						|| contentType.contains("text/html")) {
					Object content = message.getContent();
					if (content != null) {
						messageContent = content.toString();
					}
				}

				// print out details of each message
				System.out.println("Message #" + (i + 1) + ":");
				System.out.println("\t From: " + from);
				System.out.println("\t Subject: " + subject);
				System.out.println("\t Sent Date: " + sentDate);
				System.out.println("\t Message: " + messageContent);
				System.out.println("\t Attachments: " + attachFiles);
			}

			// disconnect
			folderInbox.close(false);
			store.close();
		} catch (NoSuchProviderException ex) {
			System.out.println("No provider for pop3.");
			ex.printStackTrace();
		} catch (MessagingException ex) {
			System.out.println("Could not connect to the message store");
			ex.printStackTrace();
		} catch (IOException ex) {
			ex.printStackTrace();
		}
	}

	/**
	 * Runs this program with Gmail POP3 server
	 */
	public static void main(String[] args) {
		String host = "pop.gmail.com";
		String port = "995";
		String userName = "your_email";
		String password = "your_password";

		String saveDirectory = "E:/Attachment";

		EmailAttachmentReceiver receiver = new EmailAttachmentReceiver();
		receiver.setSaveDirectory(saveDirectory);
		receiver.downloadEmailAttachments(host, port, userName, password);

	}
} 

The program above will save attachments into a specified directory, and print out details of each received message, including file names of the attachments.

 

NOTES:

You need to use JavaMail jar files. If you use Maven, add the following dependency to the pom.xml file:

<dependency>
	<groupId>com.sun.mail</groupId>
	<artifactId>javax.mail</artifactId>
	<version>1.6.2</version>
</dependency>

This will add the javax.mail-VERSION.jar and activation-VERSION.jar to the project's classpath. If you have to add them manually, download from JavaMail Project page.

 

Other JavaMail Tutorials:


About the Author:

is certified Java programmer (SCJP and SCWCD). He began programming with Java back in the days of Java 1.4 and has been passionate about it ever since. You can connect with him on Facebook and watch his Java videos on YouTube.

Add comment

   


Comments 

#62Thanushree Y R2021-09-15 05:29
Can anyone send me a java code to download an folder from email and read that save that to one folder
Quote
#61ketan2020-06-05 06:21
attachment download but not read body message
// this part may be the message content
messageContent = part.getContent().toString();
Quote
#60good2020-04-08 19:43
thanks for your detail example
Quote
#59Justin2019-09-18 05:04
Hi @Nam Ha Minh ,
Thanks for nice post. i want to retrieve email messageID using folderInbox.search(), Can you guide me to achieve this?
Quote
#58Youssouf TIMERA2019-06-05 06:51
Thank you a lot for this tutorial.
I have a problem with recieved pdf file. I always get a encrypted name when I call the getFileName method.
Do you have any solution for this ?
Quote