일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | 2 | 3 | 4 | 5 | 6 | 7 |
8 | 9 | 10 | 11 | 12 | 13 | 14 |
15 | 16 | 17 | 18 | 19 | 20 | 21 |
22 | 23 | 24 | 25 | 26 | 27 | 28 |
29 | 30 | 31 |
- generate pojos
- 초기 세팅
- Java
- swagger
- React
- spring boot
- JavaScript
- dto valid
- NextJS
- generate entity
- ollama langflow
- CentOS6
- memcached
- Next.js 14
- java8
- header setting
- 초기 구축
- 헤더 설정
- docker
- JPA
- java9
- spring
- docker 설치
- MySQL
- jpa entity자동
- 도커
- SpringBoot
- custom valid
- 리눅스
- jvm
- Today
- Total
개발자의 길
mx를 이용한 smtp 메일존재여부 EmailValidator체크 본문
전자메일을 검증하기 위한 몇가지 방법이 있다.
1. 가장 간단한 @ 또는 .이 있는지 정규식으로 검사하는 방법
2. E-mail로 인증코드를 보내서 재확인하는 방법
3. E-mail이 존재하는지 실제로 MX서버에서 체크하는 방법 |
이렇게 있다.
1, 2는 간단한 코딩으로 끝나고 자주 이용하지만, 3번을 하려면 막막하다...
이미 입력된 이용자의 e-mail을 검증하기 위한 방법도 3번이 가장 적합하다.
이럴때, 3번을 구현해서 사용하면 매우 편할것이다.
다음 소스는 http://www.rgagnon.com에서 가져다가 버그가 생길 소지가 있는 부분을 수정해 놨으며, 대충 주석도 번역해 놓았다...
유용하게 쓰자~!
package com;
import java.io.*;
import java.net.*;
import java.util.*;
import javax.naming.*;
import javax.naming.directory.*;
public class EMailValidator {
/**
* SMTP 서버의 메시지 스트림에서 PREFIX (결과값) 내용을 읽어온다.
*
* @param in
* @return
* @throws IOException
*/
private static int hear(BufferedReader in) throws IOException {
String line = null;
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;
}
/**
* 소켓에 메시지를 보낸다.
*
* @param wr
* @param text
* @throws IOException
*/
private static void say(BufferedWriter wr, String text) throws IOException {
wr.write(text + "\r\n");
wr.flush();
}
private static ArrayList getMX(String hostName) throws NamingException {
// 도메인에서 MX레코드를 찾기를 시도
Hashtable 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");
// 만약 MX레코드가 없으면, 그 자신 MX서버인지 시도해 본다.
if ((attr == null) || (attr.size() == 0)) {
attrs = ictx.getAttributes(hostName, new String[] { "A" });
attr = attrs.get("A");
if (attr == null)
throw new NamingException("호스트명이 잘못되었습니다. '" + hostName + "'");
}
// 발견한 경우에 다음을 수행한다.
ArrayList res = new ArrayList();
NamingEnumeration en = attr.getAll();
while (en.hasMore()) {
String x = (String) en.next();
String f[] = x.split(" ");
if (f[1].endsWith("."))
f[1] = f[1].substring(0, (f[1].length() - 1));
res.add(f[1]);
}
return res;
}
/**
* 메일이 유효한가 여부를 확인하는 메서드
*
* @param address
* @return
*/
public static boolean isAddressValid(String address) {
// 도메인네임 구분자'@'위치를 찾는다.
int pos = address.indexOf('@');
// 없다면, 잘못된 e-mail
if (pos == -1)
return false;
// 메일 주소를 찾기위해서 도메인명 만을 구한다.
String domain = address.substring(++pos);
ArrayList mxList = null;
try {
// DNS에서 MX레코드를 찾는다.
mxList = getMX(domain);
} catch (NamingException ex) {
return false;
}
if (mxList.size() == 0)
return false;
// 각각의 MX에 SMTP 유효성 체크를 한다.
for (int mx = 0; mx < mxList.size(); mx++) {
boolean valid = false;
Socket skt = null;
BufferedReader rdr = null;
BufferedWriter wtr = null;
try {
int res;
skt = new Socket((String) mxList.get(mx), 25);
rdr = new BufferedReader(new InputStreamReader(skt
.getInputStream()));
wtr = new BufferedWriter(new OutputStreamWriter(skt
.getOutputStream()));
res = hear(rdr);
if (res != 220) {
throw new Exception("SMTP 메시지 Header가 잘못되었습니다.");
}
say(wtr, "EHLO " + domain);
res = hear(rdr);
if (res == 500) {
System.out.println("HELO로 재시도합니다.");
say(wtr, "HELO " + domain);
res = hear(rdr);
if (res != 250)
throw new Exception("ESMTP가 아닙니다.");
}
if (res != 250) {
throw new Exception("ESMTP가 아닙니다.");
}
say(wtr, "MAIL FROM: <" + address + ">");
res = hear(rdr);
if (res != 250) {
throw new Exception("발송 거부되었습니다.");
}
say(wtr, "RCPT TO: <" + address + ">");
res = hear(rdr);
say(wtr, "RSET");
try {
hear(rdr);
} catch (Exception e) {
}
say(wtr, "QUIT");
// hear(rdr); // quit하는 경우 수신을 하지 않아도 무방하다.
if (res != 250) {
throw new Exception("메일주소가 잘못되었습니다. (서버에서 수신자 없음 메시지 리턴)");
}
valid = true;
} catch (Exception ex) {
System.err.println(ex.getMessage());
} finally {
if (rdr != null) {
try {
rdr.close();
} catch (IOException e) {
}
}
if (wtr != null) {
try {
wtr.close();
} catch (IOException e) {
}
}
if (skt != null) {
try {
skt.close();
} catch (IOException e) {
}
}
}
if (valid)
return true;
}
return false;
}
public static void main(String args[]) {
String testData[] = { "pigmon@kornet.net" };
for (int ctr = 0; ctr < testData.length; ctr++) {
System.out.println(testData[ctr] + " : "
+ isAddressValid(testData[ctr]));
}
return;
}
}
'4. JAVA' 카테고리의 다른 글
[자바] 암호화 만들기 (0) | 2011.01.05 |
---|---|
[JAVA] EHCache를 이용한 캐시 사용 (0) | 2010.10.01 |
Quartz의 CronTrigger를 이용한 Java 프로그램 스케쥴링 (0) | 2010.04.23 |
JAVA SAX 이용하여 XML Parser 만들기 (0) | 2010.04.15 |
[자바]smtp프로토콜 이용, 이메일 실제 존재 여부 체크 (1) | 2010.03.25 |
이 포스팅은 쿠팡 파트너스 활동의 일환으로, 이에 따른 일정액의 수수료를 제공받습니다.