지난 시간에는 실제적인 메일 전송은 하지 않고, 로그로만 출력했는데, 찜찜한 관계로 한번 해보도록 하자.
자바 진영에서는 JavaMail이라는 훌륭한(?) 메일 라이브러리를 제공한다. IMAP/POP3/SMTP를 지원한다. 이 JavaMail을 사용하기 위해서는 JAF(JavaBeans Activation Framework)가 필요하다. JDK 1.6부터는 자체적으로 포함되어있다. 여기서는 JDK 1.5를 사용하는 관계로 다운 받도록 하겠다.
1. 라이브러리 설치하기
- JavaMail의 mail.jar과 JAF의 activation.jar을 클래스패스에 잡아주자.(mail.jar는 mailapi.jar + imap.jar + smtp.jar + pop3.jar라고 보면 된다.)
JavaMail 1.4.2
http://java.sun.com/products/javamail/downloads/index.html
JavaBeans Activation Framework 1.1.1
http://java.sun.com/javase/technologies/desktop/javabeans/jaf/downloads/index.html
2. SMTPMailSendManager 클래스 만들기
- MailSendManager 인터페이스를 구현한 SMTPMailSendManager 클래스를 만들어보자.
package kr.kangwoo.postman.service;
import java.io.UnsupportedEncodingException;
import java.util.Properties;
import javax.mail.Authenticator;
import javax.mail.Message;
import javax.mail.MessagingException;
import javax.mail.PasswordAuthentication;
import javax.mail.Session;
import javax.mail.Transport;
import javax.mail.internet.InternetAddress;
import javax.mail.internet.MimeMessage;
import kr.kangwoo.postman.core.MailException;
import kr.kangwoo.postman.core.MailStatusCode;
import kr.kangwoo.postman.core.MessageException;
import kr.kangwoo.util.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
public class SMTPMailSendManager implements MailSendManager {
private Logger logger = LoggerFactory.getLogger(getClass());
private String protocol = "smtp";
private String type = "text/html; charset=KSC5601";
private String userName;
private String password;
private String host = "127.0.0.1";
private int port = 25;
private boolean starttlsEnable = false;
public void setUserName(String userName) {
this.userName = userName;
}
public void setPassword(String password) {
this.password = password;
}
public void setHost(String host) {
this.host = host;
}
public void setPort(int port) {
this.port = port;
}
public void setType(String type) {
this.type = type;
}
public void setStarttlsEnable(boolean starttlsEnable) {
this.starttlsEnable = starttlsEnable;
}
public void send(String toAddress, String toName, String fromAddress,
String fromName, String subject, String content) throws MessageException {
logger.debug("[{}] 메일 발송 시작", toAddress);
try {
Properties props = new Properties();
props.put("mail.transport.protocol", protocol);
props.put("mail.smtp.host", host);
props.put("mail.smtp.port", String.valueOf(port));
Authenticator authenticator = null;
if (StringUtils.isNotBlank(userName)) {
props.put("mail.smtp.auth", "true");
authenticator = new SMTPAuthenticator(userName, password);
}
if (starttlsEnable) {
props.put("mail.smtp.starttls.enable", Boolean.toString(starttlsEnable));
}
Session session = Session.getInstance(props, authenticator);
MimeMessage message = new MimeMessage(session);
message.setFrom(new InternetAddress(fromAddress, fromName));
message.addRecipient(Message.RecipientType.TO, new InternetAddress(toAddress, toName));
message.setSubject(subject);
message.setContent(content, type);
Transport.send(message);
logger.debug("[{}] 메일 발송 성공", toAddress);
} catch (UnsupportedEncodingException e) {
logger.debug("[{}] 메일 발송 실패", toAddress);
throw new MailException(MailStatusCode.SEND_FAIL, "메일을 발송하는 중 에러가 발생했습니다.", e);
} catch (MessagingException e) {
logger.debug("[{}] 메일 발송 실패", toAddress);
throw new MailException(MailStatusCode.SEND_FAIL, "메일을 발송하는 중 에러가 발생했습니다.", e);
}
}
class SMTPAuthenticator extends Authenticator {
PasswordAuthentication passwordAuthentication;
SMTPAuthenticator(String userName, String password) {
passwordAuthentication = new PasswordAuthentication(userName, password);
}
public PasswordAuthentication getPasswordAuthentication() {
return passwordAuthentication;
}
}
}
- 자바메일을 이용해서 메일 전송을 구현하였다. 사용자 인증을 위해서 Authenticator을 상속받은 SMTPAuthenticator 클래스를 내부에 만들었다. 그리고 starttls을 사용하기 위해 변수를 선언하였다. (starttls게 뭔지 본인은 모른다. 궁금하신분은 RFC-2487)를 참고 바란다.
3. PostMan 실행해보기
- 지난 시간에 만든 PostMan 클래스를 수정해주자. 로그로만 메일 내용을 출력해주던 SimpleMailSendManager 클래스를 지금 만든 SMTPMailSendManager 클래스로 바꾸자.
package kr.kangwoo.postman.core;
public class PostMan {
// ... 생 략 ...
public static void main(String[] args) {
PostMan man = new PostMan();
MailDao mailDao = new SimpleMailDao();
MailTemplateDao mailTemplateDao = new SimpleMailTemplateDao();
SimpleMailManager mailManager = new SimpleMailManager();
mailManager.setMailDao(mailDao);
FreemarkerMailTemplateManager mailTemplateManager = new FreemarkerMailTemplateManager();
mailTemplateManager.setMailTemplateDao(mailTemplateDao);
SMTPMailSendManager mailSendManager = new SMTPMailSendManager();
mailSendManager.setHost("smtp.gmail.com");
mailSendManager.setPort(587);
mailSendManager.setStarttlsEnable(true);
mailSendManager.setUserName("계정명");
mailSendManager.setPassword("계정비밀번호 ");
man.setMailManager(mailManager);
man.setMailTemplateManager(mailTemplateManager);
man.setMailSendManager(mailSendManager);
man.run();
}
}
- 여기서는 gmail 계정을 사용하였다.(gmail 계정을 사용할려면 starttls를 사용함으로 해야한다.) 발송할 대상을 바꾸고(꼭 바꿔주시길 바란다.!!! 지난 예제로 실행하면 본인한테 메일이 온다.) 실행해보자.
- 어제 소스를 그대로 사용하시는분은, 무한 루프를 도는 관계로 꼭 강제적으로 중지시켜주기 바란다. 안그러면 미워할거다.
- gmail, naver, daum은 잘 도착한다. ^^;