The JavaMail API allows developers writing code for searching e-mail messages within user’s inbox. This can be accomplished by calling the search() function which is provided by the Folderclass:

 

Message[] search(SearchTerm term)

 

This method returns an array of Message objects which match a search criterion specified by a subclass of SearchTerm class. We need to create a class that extends from SearchTerm class and overrides its method match(). For example:

SearchTerm term = new SearchTerm() {
	public boolean match(Message message) {
		try {
			if (message.getSubject().contains("Java")) {
				return true;
			}
		} catch (MessagingException ex) {
			ex.printStackTrace();
		}
		return false;
	}
};
 

As we can see, the match() method above returns true if a message with subject containing the word “Java”. In other words, the search term above will match all messages having the word “Java” in its Subject field. And pass this new SearchTerm object to the search method as follows:

Message[] foundMessages = folder.search(term);
 

The search() method returns an empty array if no matches were found. Subclasses of Folder class implements this search functionality for corresponding protocol, i.e IMAPFolder class and POP3Folder class.

The following program connects to a mail server via IMAP protocol and searches for all messages containing the word “JavaMail” in the Subject field, within the inbox folder. Here is the code:

package net.codejava.mail;

import java.util.Properties;

import javax.mail.Folder;
import javax.mail.Message;
import javax.mail.MessagingException;
import javax.mail.NoSuchProviderException;
import javax.mail.Session;
import javax.mail.Store;
import javax.mail.search.SearchTerm;

/**
 * This program demonstrates how to search for e-mail messages which satisfy
 * a search criterion.
 * @author www.codejava.net
 *
 */
public class EmailSearcher {

	/**
	 * Searches for e-mail messages containing the specified keyword in
	 * Subject field.
	 * @param host
	 * @param port
	 * @param userName
	 * @param password
	 * @param keyword
	 */
	public void searchEmail(String host, String port, String userName,
			String password, final String keyword) {
		Properties properties = new Properties();

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

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

		Session session = Session.getDefaultInstance(properties);

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

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

			// creates a search criterion
			SearchTerm searchCondition = new SearchTerm() {
				@Override
				public boolean match(Message message) {
					try {
						if (message.getSubject().contains(keyword)) {
							return true;
						}
					} catch (MessagingException ex) {
						ex.printStackTrace();
					}
					return false;
				}
			};

			// performs search through the folder
			Message[] foundMessages = folderInbox.search(searchCondition);

			for (int i = 0; i < foundMessages.length; i++) {
				Message message = foundMessages[i];
				String subject = message.getSubject();
				System.out.println("Found message #" + i + ": " + subject);
			}

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

	/**
	 * Test this program with a Gmail's account
	 */
	public static void main(String[] args) {
		String host = "imap.gmail.com";
		String port = "993";
		String userName = "your_email";
		String password = "your_password";
		EmailSearcher searcher = new EmailSearcher();
		String keyword = "JavaMail";
		searcher.searchEmail(host, port, userName, password, keyword);
	}

}
 

We can combine multiple properties of a Message object to create more complex search criterion, for example:

if (message.getSubject().contains(keyword)
		&& message.getSentDate().after(aDate)) {
	return true;
}


 

Following are some useful search criteria:

Search criterion for From field:

package net.codejava.mail;

import javax.mail.Address;
import javax.mail.Message;
import javax.mail.MessagingException;
import javax.mail.search.SearchTerm;

public class FromFieldSearchTerm extends SearchTerm {
	private String fromEmail;
	
	public FromFieldSearchTerm(String fromEmail) {
		this.fromEmail = fromEmail;
	}
	
	@Override
	public boolean match(Message message) {
		try {
			Address[] fromAddress = message.getFrom();
			if (fromAddress != null && fromAddress.length > 0) {
				if (fromAddress[0].toString().contains(fromEmail)) {
					return true;
				}
			}
		} catch (MessagingException ex) {
			ex.printStackTrace();
		}
		
		return false;
	}
	
} 
 

Search criterion for Sent Date field:

package net.codejava.mail;

import java.util.Date;

import javax.mail.Message;
import javax.mail.MessagingException;
import javax.mail.search.SearchTerm;

public class SentDateSearchTerm extends SearchTerm {
	private Date afterDate;
	
	public SentDateSearchTerm(Date afterDate) {
		this.afterDate = afterDate;
	}
	
	@Override
	public boolean match(Message message) {
		try {
			if (message.getSentDate().after(afterDate)) {
				return true;
			}
		} catch (MessagingException ex) {
			ex.printStackTrace();
		}
		return false;
	}

} 
 

Search criterion for message content:

package net.codejava.mail;

import java.io.IOException;

import javax.mail.Message;
import javax.mail.MessagingException;
import javax.mail.search.SearchTerm;

public class ContentSearchTerm extends SearchTerm {
	private String content;
	
	public ContentSearchTerm(String content) {
		this.content = content;
	}
	
	@Override
	public boolean match(Message message) {
		try {
			String contentType = message.getContentType().toLowerCase();
			if (contentType.contains("text/plain")
					|| contentType.contains("text/html")) {
				String messageContent = message.getContent().toString();
				if (messageContent.contains(content)) {
					return true;
				}
			}
		} catch (MessagingException ex) {
			ex.printStackTrace();
		} catch (IOException ex) {
			ex.printStackTrace();
		}
		return false;
	}

}
 

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.



Attachments:
Download this file (EmailSearcher.java)EmailSearcher.java[Sample program for searching e-mail messages]2 kB

Add comment

   


Comments 

#18haritha2022-05-19 06:25
your code helps me alot
but for searching messages based on sentdate is not working for me..
could u please share whole code with me
Quote
#17Vadodariya Tushar2020-10-05 05:35
Hiiiiiiiiiii,
100% Run Code
Quote
#16Gaurav Kuakde2019-12-19 22:52
Quoting Gaurav Kukade:
Hi,
I am getting this error while trying this code.
Could not connect to the message store.
javax.mail.MessagingException: sun.security.validator.ValidatorException: ........
How to fix this issue? Or at least avoid the ssl things?

IT WAS BECAUSE AVAST ANTIVIRUS ----- UNINSTALL IT
Quote
#15Gaurav Kukade2019-12-16 05:41
Hi,
I am getting this error while trying this code.
Could not connect to the message store.
javax.mail.MessagingException: sun.security.validator.ValidatorException: PKIX path building failed: sun.security.provider.certpath.SunCertPathBuilderException: unable to find valid certification path to requested target;
I have tried adding cert using Portecle.
How to fix this issue? Or at least avoid the ssl things?
Quote
#14mohana2019-05-24 02:59
String subject = message.getSubject(); getting different subject ( Delivery Status Notification (Failure)) for the kickback back mail from Mail Delivery System
can any one help me how to read original mail subject for kick back mails from Mail Delivery System.
Quote