使用Java验证电子邮件

34

有没有办法在Java代码中验证电子邮件地址是否有效?这里的“有效”不仅指它的格式是否正确(someone@domain.subdomain),而且还要能够确定它是一个真正活跃的电子邮件地址。

我几乎可以确定没有一种100%可靠的方法来做到这一点,因为这样的技术将成为垃圾邮件发送者的梦想。但也许有一些技术可以提供有关地址是否“真实”的有用指示。


3
这个问题也有助于回答这个问题:应该对电子邮件地址验证进行多少检查 - David
9个回答

52

这是我手头的内容。为了检查地址是否具有有效格式,这里提供一个正则表达式,验证它几乎符合rfc2822(它不能捕获一些奇怪的边角情况)。我在去年在互联网上找到了它。

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");
}

那将解决简单的语法问题(在大多数情况下)。我知道的另一种检查方法是让你检查域名是否有MX记录。它看起来像这样:

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

我也在网络上找到了这个。它来自这个链接

如果这两个都通过了,那么您就有很大的机会拥有一个有效的地址。至于地址本身(而不仅仅是域名),是否完整等等,您确实无法检查。

请注意,第二次检查非常费时。它可能需要从毫秒到超过30秒的时间(如果DNS没有响应并超时)。这不是为大量人尝试实时运行的东西。

希望这有所帮助。

编辑

我想指出,至少在正则表达式之外,还有更好的方法来检查基本的有效性。Don和Michael指出Apache Commons中有一些东西,我最近发现您可以在InternetAddress上使用.validate(),让Java检查该地址是否真正符合RFC-8222,这肯定比我的正则表达式更准确。


12
这是一个指向Apache Commons Validator库中的电子邮件验证器类的链接。 - Michael Myers
@MBCook 是我还是这个正则表达式让只有一个字母的域名的电子邮件通过了?例如 test@test.b。我应该改变什么来禁止它?谢谢! - Julia
@Julia 可能需要,老实说,我不太确定哪个部分需要修改。目前,我一直在使用InternetAddress类来验证电子邮件地址的基本有效性。 - MBCook
1
这并没有回答问题。 - Thorbjørn Ravn Andersen
1
就此问题而言,正则表达式似乎不允许在地址的名称部分中包含句点“.”。 - Scott
显示剩余2条评论

3

您无法真正验证电子邮件是否存在,可以查看我在这里回答的一个非常相似的问题:电子邮件SMTP验证器


2

如果没有发送电子邮件,那么很难达到100%的准确性,但是如果您在主机上进行DNS查找,这至少可以告诉您它是一个可行的目标系统。


1
DNS查询不一定是个好主意,因为DNS记录可能有MX记录但没有主机记录。 - FelixM

2

Apache Commons提供了一个电子邮件验证器类,您可以使用它。只需将您的电子邮件地址作为参数传递给isValid方法即可。


1
唯一确定的方法是实际发送邮件并确保其被阅读。
让您的注册过程包含一步,需要回复仅在电子邮件中找到的信息。这是其他人所做的。

个人而言,我一直在使用临时电子邮件服务。例如Guerrillamail。因此,即使您“解析”了有效的电子邮件地址...它真的有效吗?目前,如果用户点击链接-是的。一周后呢?也许不再有效。在我看来,您必须重新设计。不要总是要求电子邮件,让用户匿名地使用您的服务,并仅在他们真正需要的附加好处时注册一个新的个人帐户。 - Martin Andersson

1

对主机名进行DNS查找,以查看其是否存在。理论上,您也可以启动与邮件服务器的连接,并查看它是否告诉您收件人是否存在,但我认为许多服务器都会假装知道地址,然后无论如何都拒绝电子邮件。


我认为如果你这样做(询问邮件服务器收件人是否存在),一些/大多数服务器会将你列入灰名单。 - opyate

0

我不是100%确定,但是发送一个RCPT SMTP命令到邮件服务器来确定收件人是否有效,这不是可能的吗?虽然检查有效MX主机的建议比上面的建议更昂贵,但它也是最准确的。


-1
如果您正在使用GWT,则无法使用InternetAddress,并且MBCook提供的模式非常可怕。这里有一个不那么可怕的正则表达式(可能不太准确):
public static boolean isValidEmail(String emailAddress) {
    return emailAddress.contains(" ") == false && emailAddress.matches(".+@.+\\.[a-z]+");
}

-2
public static boolean isValidEmail(String emailAddress) {
    return emailAddress.contains(" ") == false && emailAddress.matches(".+@.+\\.[a-z]+");
} 

你似乎完全没有读懂问题。OP明确表示他们不是在寻找地址格式是否有效,而是在寻找地址是否是“真实的、活着的”地址。 - Andrew Barber
是的,如果你想用正则表达式验证电子邮件地址,你需要使用这个庞然大物(太大了,无法在评论中使用):http://www.ex-parrot.com/~pdw/Mail-RFC822-Address.html - 0x89

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接