Есть ли способ проверить в коде Java, что адрес электронной почты действителен. Под допустимым я подразумеваю не только то, что он в правильном формате ([email protected]), но это настоящий активный адрес электронной почты.
Я почти уверен, что не существует 100% надежного способа сделать это, потому что такая техника была бы мечтой спамеров. Но, возможно, есть какой-то метод, который дает какое-то полезное представление о том, является ли адрес «настоящим» или нет.




Без отправки электронной почты было бы сложно получить 100%, но если вы выполните поиск DNS на хосте, это должно, по крайней мере, сказать вам, что это жизнеспособная система назначения.
Поиск DNS не обязательно является хорошей идеей, потому что запись DNS может иметь запись MX, но не для хоста.
Выполните поиск DNS по имени хоста, чтобы узнать, существует ли оно. Теоретически вы также можете инициировать соединение с почтовым сервером и посмотреть, сообщает ли он, существует ли получатель, но я думаю, что многие серверы притворяются, что знают адрес, а затем все равно отклоняют электронное письмо.
Я думаю, что некоторые / большинство серверов заносят вас в серый список, если вы это сделаете (спрашивая почтовый сервер, существует ли получатель).
Вот что у меня есть. Чтобы проверить, что адрес является допустимым форматом, вот регулярное выражение, которое проверяет, что он почти 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 не отвечает и истекает время ожидания). Это не то, что нужно пробовать запускать в реальном времени для большого количества людей.
Надеюсь это поможет.
РЕДАКТИРОВАТЬ
Я хотел бы указать, что, по крайней мере, вместо регулярного выражения есть более эффективные способы проверки базовой действительности. Дон и Майкл отмечают, что в Apache Commons что-то есть, и недавно я узнал, что вы можете использовать .validate () в InternetAddress, чтобы Java проверяла, действительно ли адрес соответствует RFC-8222, что, безусловно, более точно, чем мое регулярное выражение.
Я думаю, что у Apache Commons есть валидатор электронной почты, который вы могли бы использовать вместо этого регулярного выражения-монстра.
Да: commons.apache.org/validator/apidocs/org/apache/commons/…
Ну, что ты знаешь? У Apache так много замечательных вещей в свободном доступе. Я согласен, что регулярное выражение ужасно. Я рад, что мне не пришлось это писать.
@MBCook - это я, или это регулярное выражение пропускает электронную почту с однобуквенным доменом? например [email protected] Что мне нужно изменить, чтобы запретить это? спасибо!
@Julia Вероятно, да, и, честно говоря, я не совсем уверен, какую часть нужно изменить для этого. На этом этапе я использовал класс InternetAddress для проверки адресов электронной почты на базовую достоверность.
Это не отвечает на вопрос.
FWIW регулярное выражение, похоже, не допускает периодов "." в названии адреса
Вы не можете действительно проверить, существует ли электронное письмо, см. Мой ответ на очень похожий вопрос здесь: Валидатор электронной почты SMTP
Общество Apache также предоставляет класс валидатора электронной почты, который вы можете использовать. Просто передайте свой адрес электронной почты в качестве аргумента методу isValid.
Я не уверен на 100%, но разве нельзя отправить SMTP-команду RCPT на почтовый сервер, чтобы определить, действителен ли получатель? Проверка действительного хоста MX будет даже дороже, чем предложенное выше, но также будет наиболее точным.
Если вы используете GWT, вы не можете использовать InternetAddress, а шаблон, предоставляемый MBCook, довольно пугающий.
Вот менее страшное регулярное выражение (может быть не таким точным):
public static boolean isValidEmail(String emailAddress) {
return emailAddress.contains(" ") == false && emailAddress.matches(".+@.+\.[a-z]+");
}
Единственный способ убедиться в этом - это отправить письмо и прочитать его.
Пусть в процессе регистрации будет этап, требующий ответа на информацию, найденную только в электронном письме. Это то, что делают другие.
Лично я постоянно пользуюсь услугами временной электронной почты. Например, как Партизанский. Таким образом, даже если вы "проанализируете" действующий адрес электронной почты ... действительно ли он действителен? Пока что если пользователь перешел по ссылке - да. Через неделю? Возможно. На мой взгляд, вы должны переделать свой дизайн. Не просите электронную почту все время, позвольте пользователям использовать ваши услуги анонимно и пусть они регистрируют новую личную учетную запись только для дополнительных преимуществ, которые они действительно ищут.
public static boolean isValidEmail(String emailAddress) {
return emailAddress.contains(" ") == false && emailAddress.matches(".+@.+\.[a-z]+");
}
Похоже, вы вообще не читали вопрос. OP специально сказал, что они нет смотрят, действителен ли формат адреса, но является ли адрес «реальным, живым» адресом.
Да нет. Если вы хотите проверять адреса электронной почты с помощью регулярных выражений, вам нужно использовать это чудовище (слишком большое для комментария): ex-parrot.com/~pdw/Mail-RFC822-Address.html
Этот вопрос также будет полезен при ответе на этот вопрос: как-далеко-нужно-одно-взять-подтверждение-адреса электронной почты