Verify email in Java

Dónal picture Dónal · Sep 30, 2008 · Viewed 54k times · Source

Is there any way to verify in Java code that an e-mail address is valid. By valid, I don't just mean that it's in the correct format ([email protected]), but that's it's a real active e-mail address.

I'm almost certain that there's no 100% reliable way to do this, because such a technique would be the stuff of spammer's dreams. But perhaps there's some technique that gives some useful indication about whether an address is 'real' or not.

Answer

MBCook picture MBCook · Sep 30, 2008

Here is what I have around. To check that the address is a valid format, here is a regex that verifies that it's nearly rfc2822 (it doesn't catch some weird corner cases). I found it on the 'net last year.

private static final Pattern rfc2822 = Pattern.compile(
        "^[a-z0-9!#$%&'*+/=?^_`{|}~-]+(?:\\.[a-z0-9!#$%&'*+/=?^_`{|}~-]+)*@(?:[a-z0-9](?:[a-z0-9-]*[a-z0-9])?\\.)+[a-z0-9](?:[a-z0-9-]*[a-z0-9])?$"
);

if (!rfc2822.matcher(email).matches()) {
    throw new Exception("Invalid address");
}

That will take care of simple syntax (for the most part). The other check I know of will let you check if the domain has an MX record. It looks like this:

Hashtable<String, String> env = new Hashtable<String, String>();

env.put("java.naming.factory.initial", "com.sun.jndi.dns.DnsContextFactory");

DirContext ictx = new InitialDirContext(env);

Attributes attrs = ictx.getAttributes(domainName, new String[] {"MX"});

Attribute attr = attrs.get("MX");

if (attr == null)
    // No MX record
else
    // If attr.size() > 0, there is an MX record

This, I also found on the 'net. It came from this link.

If these both pass, you have a good chance at having a valid address. As for if the address it's self (not just the domain), it's not full, etc... you really can't check that.

Note that the second check is time intensive. It can take anywhere from milliseconds to >30 seconds (if the DNS does not respond and times out). It's not something to try and run real-time for large numbers of people.

Hope this helps.

EDIT

I'd like to point out that, at least instead of the regex, there are better ways to check basic validity. Don and Michael point out that Apache Commons has something, and I recently found out you can use .validate() on InternetAddress to have Java check that the address is really RFC-8222, which is certainly more accurate than my regex.