Java實現通過smtp伺服器驗證郵箱的真實有效性
阿新 • • 發佈:2019-01-03
要用到commons-net-3.3.jar、dnsjava-2.1.7.jar包
大部分的國內常見郵箱都能準確驗證。
驗證頻率和數量多的話容易被封掉ip
package com.tieniu;
import java.io.IOException;
import org.apache.commons.net.smtp.SMTPClient;
import org.apache.commons.net.smtp.SMTPReply;
import org.xbill.DNS.Lookup;
import org.xbill.DNS.MXRecord;
import org.xbill.DNS.Record;
import org.xbill.DNS.Type;
public class CheckEmail {
public static final String SENDER_EMAIL = " [email protected]";//"[email protected]";
public static final String SENDER_EMAIL_SERVER = SENDER_EMAIL.split("@")[1];//"domain.com";
/**
*
* @param email The recipient's email address, it need to be validate if it is real exists or doesn't exists.
* @return True if email is real exists, false if not.
*/
public boolean checkEmailMethod(String email) {
if (!email.matches("[\\w\\.\\-] [email protected]([\\w\\-]+\\.)+[\\w\\-]+")) {
System.err.println("Format error");
return false;
}
String log = "";
String host = "";
String hostName = email.split("@")[1];
Record[] result = null;
SMTPClient client = new SMTPClient();
client.setConnectTimeout(8000); //設定連線超時時間,有些伺服器比較慢
try {
// 查詢MX記錄
Lookup lookup = new Lookup(hostName, Type.MX);
lookup.run();
if (lookup.getResult() != Lookup.SUCCESSFUL) {
log += "找不到MX記錄\n";
return false;
} else {
result = lookup.getAnswers();
}
/*
if(result.length > 1) { // 優先順序排序
List<Record> arrRecords = new ArrayList<Record>();
Collections.addAll(arrRecords, result);
Collections.sort(arrRecords, new Comparator<Record>() {
public int compare(Record o1, Record o2) {
return new CompareToBuilder().append(((MXRecord)o1).getPriority(), ((MXRecord)o2).getPriority()).toComparison();
}
});
host = ((MXRecord)arrRecords.get(0)).getTarget().toString();
}
*
*/
// 連線到郵箱伺服器
for (int i = 0; i < result.length; i++) {
System.out.println(result[i].getAdditionalName().toString());
System.out.println(((MXRecord)result[i]).getPriority());
}
int count=0;
// String tempLog ="";
for (int i = 0; i < result.length; i++) {
log="";
host = result[i].getAdditionalName().toString();
try{
client.connect(host); //連線到接收郵箱地址的郵箱伺服器
}catch(Exception e){ //捕捉連線超時的丟擲的異常
count++;
if(count>=result.length){ //如果由MX得到的result伺服器都連線不上,則認定email無效
log +="Connect mail server timeout...\n";
return false;
}
}
if (!SMTPReply.isPositiveCompletion(client.getReplyCode())) { //伺服器通訊不成功
client.disconnect();
continue;
} else {
log += "MX record about " + hostName + " exists.\n";
log += "Connection succeeded to " + host + "\n";
log += client.getReplyString();
// HELO <$SENDER_EMAIL_SERVER> //domain.com
try{
client.login(SENDER_EMAIL_SERVER); //這一步可能會出現空指標異常
}catch(Exception e){
return false;
}
log += ">HELO "+SENDER_EMAIL_SERVER+"\n";
log += "=" + client.getReplyString();
client.setSender(SENDER_EMAIL);
if(client.getReplyCode()!=250){ //為解決hotmail有的MX可能出現=550 OU-001 (SNT004-MC1F43) Unfortunately, messages from 116.246.2.245 weren't sent.
client.disconnect();
continue; //把client.login 和client.setSender放在迴圈體內,這樣所有的如果某mx不行就換其他mx,但這樣會對無效的郵箱進行所有mx遍歷,耗時
}
log += ">MAIL FROM: <"+SENDER_EMAIL+">\n";
log += "=" + client.getReplyString();
// RCPT TO: <$email>
try{
client.addRecipient(email);
}catch(Exception e){
return false;
}
log += ">RCPT TO: <" + email + ">\n";
log += "=" + client.getReplyString();
//最後從收件郵箱伺服器返回true,說明伺服器中能夠找到此收件地址,郵箱有效
if (250 == client.getReplyCode()) {
return true;
}
client.disconnect();
}
}
// log+=tempLog;
// log += ">MAIL FROM: <"+SENDER_EMAIL+">\n";
// log += "=" + client.getReplyString();
//
// // RCPT TO: <$email>
// try{
// client.addRecipient(email);
// }catch(Exception e){
// return false;
// }
// log += ">RCPT TO: <" + email + ">\n";
// log += "=" + client.getReplyString();
//
// //最後從收件郵箱伺服器返回true,說明伺服器中能夠找到此收件地址,郵箱有效
// if (250 == client.getReplyCode()) {
// return true;
// }
} catch (Exception e) {
e.printStackTrace();
} finally {
try {
client.disconnect();
} catch (IOException e) {
}
// print log
System.out.println(log);
}
return false;
}
/**
* This method is more accurate than checkEmailMethod(String email);
*
* @param email The recipient's email address, it need to be validate if it is real exists or doesn't exists.
* @return True if email is real exists, false if not.
*/
public boolean checkEmail(String email){
if(email.split("@")[1].equals("qq.com")){
if( checkEmailMethod(email) && checkEmailMethod(email) && checkEmailMethod(email)){
return true;
}else{
return false;
}
}
return checkEmailMethod(email);
}
public static void main(String[] args) {
CheckEmail ce = new CheckEmail();
if(ce.checkEmail(" [email protected]")){
System.out.println("true");
}else{
System.out.println("false");
}
}
}
其中還寫了一點開發過程中的相關文件,生成了該功能相應的jar包。也生成了dll,寫了供C#呼叫的使用方法。很簡單。
這裡附上附件的連結:http://pan.baidu.com/s/1jHpdDjC 密碼:wio6