34

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 (someone@domain.subdomain), 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.

Dónal
  • 185,044
  • 174
  • 569
  • 824
  • 3
    This question will also be helpful in answering this question: [how-far-should-one-take-e-mail-address-validation](http://stackoverflow.com/questions/3232/how-far-should-one-take-e-mail-address-validation) – David Sep 30 '08 at 16:04

9 Answers9

52

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.

MBCook
  • 14,424
  • 7
  • 37
  • 41
  • I think Apache commons has an e-mail validator that you could use instead of that monster regex. – Dónal Sep 30 '08 at 16:26
  • 12
    Yes: http://commons.apache.org/validator/apidocs/org/apache/commons/validator/routines/EmailValidator.html – Michael Myers Sep 30 '08 at 21:02
  • Well what do you know? Apache has so much great stuff in the commons. I agree the regex is hideous. I'm glad I didn't have to write it. – MBCook Sep 30 '08 at 21:36
  • @MBCook is it me, or this regex lets the email with one-letter domain to pass? eg test@test.b What should i change to forbid that? thanx! – Julia Sep 21 '11 at 05:02
  • @Julia It probably does, and honestly I'm not terribly sure which part would have to change for that. At this point I've been using the InternetAddress class to verify email addresses for basic validity. – MBCook Sep 21 '11 at 15:41
  • 1
    This doesn't answer the question. – Thorbjørn Ravn Andersen Aug 20 '12 at 06:21
  • 1
    FWIW the regex doesn't seem to allow periods "." in the name portion of the address – Scott May 31 '14 at 15:02
3

You cannot really verify that an email exists, see my answer to a very similar question here: Email SMTP validator

Community
  • 1
  • 1
WMR
  • 12,661
  • 5
  • 35
  • 30
2

Without sending an email, it could be hard to get 100%, but if you do a DNS lookup on the host that should at least tell you that it is a viable destination system.

Joe Skora
  • 14,735
  • 5
  • 36
  • 39
  • 1
    The DNS lookup is not necessarily a good idea because the DNS record may have an MX record but not one for a host. – FelixM Apr 20 '11 at 01:26
2

Apache commons provides an email validator class too, which you can use. Simply pass your email address as an argument to isValid method.

Ashkan Aryan
  • 3,504
  • 4
  • 30
  • 44
1

The only way you can be certain is by actually sending a mail and have it read.

Let your registration process have a step that requires responding to information found only in the email. This is what others do.

Thorbjørn Ravn Andersen
  • 73,784
  • 33
  • 194
  • 347
  • Personally, I use temporal e-mail services all the time. Like [Guerrillamail](https://www.guerrillamail.com/) for example. Thus even if you "parse" a valid e-mail address.. is it really valid? For the time being if user clicked on a link - Yes. In a week's time? Perhaps. The way I see it, you have to redo your design. Don't ask for e-mail all the time, let users consume your services anonymously and have them register a new and personal account only for added benefits they really seek. – Martin Andersson Mar 19 '13 at 21:06
1

Do a DNS lookup on the hostname to see if that exists. You could theoretically also initiate a connection to the mailserver and see if it tells you whether the recipient exists, but I think many servers pretend they know an address, then reject the email anyway.

Lasar
  • 5,175
  • 4
  • 24
  • 22
  • I think some/most servers grey-list you if you do this (asking mail server if recipient exists). – opyate Aug 21 '09 at 11:24
0

I'm not 100% sure, but isn't it possible to send an RCPT SMTP command to a mail server to determine if the recipient is valid? It would be even more expensive than the suggestion above to check for a valid MX host, but it would also be the most accurate.

Aquarelle
  • 8,864
  • 1
  • 17
  • 11
-1

If you're using GWT, you can't use InternetAddress, and the pattern supplied by MBCook is pretty scary.

Here is a less scary regex (might not be as accurate):

public static boolean isValidEmail(String emailAddress) {
    return emailAddress.contains(" ") == false && emailAddress.matches(".+@.+\\.[a-z]+");
}
Craigo
  • 3,384
  • 30
  • 22
-2
public static boolean isValidEmail(String emailAddress) {
    return emailAddress.contains(" ") == false && emailAddress.matches(".+@.+\\.[a-z]+");
} 
Andrew Barber
  • 39,603
  • 20
  • 94
  • 123
asa
  • 5
  • 1
  • You don't seem to have read the question at all. OP specifically said they were *not* looking to see if the format of the address was valid, but if the address is a 'real, live' address. – Andrew Barber Nov 08 '12 at 06:42
  • Yeah, no. If you want to validate email addresses with regular expressions, you need to use this beast (to large for a comment): http://www.ex-parrot.com/~pdw/Mail-RFC822-Address.html – 0x89 Feb 18 '14 at 12:22