언어 및 프레임워크/JAVA
JAVA - 이메일 검증 코드
이메일 검증 기능을 JAVA를 활용하여 처리할 수 있습니다.
기능 구현 코드
- 관련 이메일 검증을 위한 코드
- DNS 에 MX 레코드로 등록되어 있는 메일의 특징을 이용한 이메일 검증 로직
- naver와 같이 대표적인 이메일 주소가 아닐 경우 조금 느린 경향이 보임
- 임시 이메일 처리 로직 미 구현 상태
import java.io.*;
import java.net.*;
import java.util.*;
import javax.naming.*;
import javax.naming.directory.*;
public class SMTPMXLookup {
private static int hear(BufferedReader in) throws IOException {
String line;
int res = 0;
while ((line = in.readLine()) != null) {
String pfx = line.substring(0, 3);
try {
res = Integer.parseInt(pfx);
} catch (Exception ex) {
res = -1;
}
if (line.charAt(3) != '-') {
break;
}
}
return res;
}
private static void say(BufferedWriter wr, String text) throws IOException {
wr.write(text + "\r\n");
wr.flush();
}
private static ArrayList<String> getMX(String hostName) throws NamingException {
Hashtable<String, String> env = new Hashtable<>();
env.put("java.naming.factory.initial", "com.sun.jndi.dns.DnsContextFactory");
DirContext ictx = new InitialDirContext(env);
Attributes attrs = ictx.getAttributes(hostName, new String[]{"MX"});
Attribute attr = attrs.get("MX");
if ((attr == null) || (attr.size() == 0)) {
attrs = ictx.getAttributes(hostName, new String[]{"A"});
attr = attrs.get("A");
if (attr == null) {
throw new NamingException("No match for name '" + hostName + "'");
}
}
ArrayList<String> res = new ArrayList<>();
NamingEnumeration<?> en = attr.getAll();
while (en.hasMore()) {
String mailhost;
String x = (String) en.next();
String[] f = x.split(" ");
if (f.length == 1) {
mailhost = f[0];
} else if (f[1].endsWith(".")) {
mailhost = f[1].substring(0, (f[1].length() - 1));
} else {
mailhost = f[1];
}
res.add(mailhost);
}
return res;
}
private static Map<String, Object> returnResult(Boolean valid, String message) {
Map<String, Object> result = new HashMap<>();
if (valid) {
result.put("resultCode", "이메일 검증 확인");
} else {
result.put("resultCode", "이메일 검증 실패");
result.put("failMessage", message);
}
return result;
}
public static Map<String, Object> isAddressValid(String address) {
int pos = address.indexOf('@');
if (pos == -1) {
return returnResult(false, "이메일 형식이 아닙니다.");
}
String domain = address.substring(++pos);
ArrayList<String> mxList;
try {
mxList = getMX(domain);
} catch (NamingException ex) {
return returnResult(false, "정식 등록된 이메일 도메인이 아닙니다.");
}
if (mxList.size() == 0) {
return returnResult(false, "정식 등록된 이메일 도메인이 아닙니다.");
}
for (String o : mxList) {
try {
int res;
Socket skt = new Socket(o, 25);
BufferedReader rdr = new BufferedReader(new InputStreamReader(skt.getInputStream()));
BufferedWriter wtr = new BufferedWriter(new OutputStreamWriter(skt.getOutputStream()));
res = hear(rdr);
if (res != 220) {
return returnResult(false, "잘못된 주소입니다.");
// throw new Exception("Invalid header");
}
say(wtr, "EHLO <도메인>");
res = hear(rdr);
if (res != 250) {
return returnResult(false, "ESMTP가 아닙니다.");
// throw new Exception("Not ESMTP");
}
say(wtr, "MAIL FROM: <<이메일>>");
res = hear(rdr);
if (res != 250) {
return returnResult(false, "메일 체크가 거절 당했습니다.");
// throw new Exception("Sender rejected");
}
say(wtr, "RCPT TO: <" + address + ">");
res = hear(rdr);
say(wtr, "RSET");
hear(rdr);
say(wtr, "QUIT");
hear(rdr);
if (res != 250) {
return returnResult(false, "주소가 유효하지 않습니다.");
// throw new Exception("Address is not valid!");
}
rdr.close();
wtr.close();
skt.close();
} catch (Exception ex) {
ex.printStackTrace();
return returnResult(false, "정의되지 않은 에러 발생.");
}
}
return returnResult(true, "");
}
public static void main(String[] args) {
String testData = "<이메일>";
Map<String, Object> result = isAddressValid(testData);
System.out.println(result.get("resultCode"));
if (result.get("failMessage") != null) {
System.out.println(result.get("failMessage"));
}
}
}
댓글