1. 程式人生 > >Java實現通過smtp伺服器驗證郵箱的真實有效性

Java實現通過smtp伺服器驗證郵箱的真實有效性

要用到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