최근에 우리 회사 새내기 개발자가 e메일 보내기에 대해 약간이나마 어려움을 느낀 것 같길래 자바에서 e메일 보내는 방법을 다시 한번 정리해볼 필요가 있겠다는 생각이 들었다. 이 글에서는 JavaMail API, 스프링 API, 기타 방법으로 e메일을 발신하는 방법을 알아보기로 한다. 자바 메일 보내기

1. JavaMail API 사용

이 방법은 자바 EE의 JavaMail API를 사용하는 것이다. 웹 환경에서는 제우스(Jeus)나 웹스피어(WebSphere) 같은 자바 EE 컨테이너를 사용한다면 JavaMail 라이브러리가 기본적으로 포함됐으므로 바로 사용할 수 있고 톰캣(Tomcat) 같은 서블릿 컨테이너를 사용하는 환경이거나 웹 환경이 아니라면 Oracle 사이트에서 JavaMail API를 다운로드하거나 Maven pom.xml에 다음 의존성을 추가한다. (1.4.7이 현재 가장 안정적인 최신 버전이다.)

<dependency>
<groupId>javax.mail</groupId>
<artifactId>mail</artifactId>
<version>1.4.7</version>
</dependency>

주의할 것은 JavaMail API를 다운로드해서 사용하는 경우 자바 5나 그 미만의 환경이라면 JavaBeans Activation Framework도 다운로드해야 한다. 준비됐으면 다음 예제와 같이 자바 프로그램에서 메일을 보낼 수 있다.

// 먼저 환경 정보를 설정해야 한다.
// 메일 서버 주소를 IP 또는 도메인 명으로 지정한다.
Properties props = System.getProperties();
props.setProperty("mail.smtp.host", "111.222.33.44");

// 위 환경 정보로 "메일 세션"을 만들고 빈 메시지를 만든다
Session session = Session.getDefaultInstance(props);
MimeMessage msg = new MimeMessage(session);

try {
// 발신자, 수신자, 참조자, 제목, 본문 내용 등을 설정한다
msg.setFrom(new InternetAddress("aaa@bbb.co.kr", "김유신"));
msg.addRecipient(Message.RecipientType.TO, new InternetAddress("ccc@ddd.co.kr", "연개소문"));
msg.addRecipient(Message.RecipientType.TO, new InternetAddress("eee@fff.co.kr", "선덕여왕"));
msg.addRecipient(Message.RecipientType.CC, new InternetAddress("ggg@hhh.co.kr", "의자왕"));
msg.setSubject("제목이 이러저러합니다");
msg.setContent("본문이 어쩌구저쩌구합니다", "text/html; charset=utf-8");

// 메일을 발신한다
Transport.send(msg);
} catch (Exception e) {
// 적절히 처리
}

위에서 17행을 보면 내용 형식을 text/html로 설정했기 때문에 내용이 html로 들어가야 한다. text/plain으로 하면 html 태그가 없는 평문으로 작성하면 된다. 그리고 문자셋은 utf-8로 했는데 ks_c_5601-1987이나 euc-kr도 일반적으로 사용되는 문자셋이다. 보다 세밀한 기능을 사용하려면 API 문서에서 각 클래스의 생성자나 메서드를 잘 살펴보기 바란다. 로깅 기능이나 파일 첨부 등 다양한 기능을 추가할 수 있다. 예를 들어 파일 첨부는 다음과 같이 가능하다. 위 17행 대신 들어갈 내용이다.

MimeMultipart multipart = new MimeMultipart();

MimeBodyPart part = new MimeBodyPart();
part.setContent("본문이 어쩌구저쩌구합니다", "text/html; charset=utf-8");
multipart.addBodyPart(part);

part = new MimeBodyPart();
FileDataSource fds = new FileDataSource("파일 경로");
part.setDataHandler(new DataHandler(fds));
part.setFileName("파일명");
multipart.addBodyPart(part);

msg.setContent(multipart);

2. Spring API 사용

스프링 프레임웍을 사용한다면 위의 JavaMail API를 래핑(wrapping)한 클래스를 사용해 약간 더 간편하게 e메일을 보낼 수 있다. (래핑 개념이므로 JavaMail API는 결국 클래스 경로에 잡혀 있어야 한다. 1번 방법의 앞 부분을 다시 보라~) 간단한 예시는 다음과 같다. 텍스트 메일을 보내는 경우다.

// Spring의 메일 발신 클래스를 하나 선언하고 서버 정보를 설정한다.
JavaMailSenderImpl mailSender = new JavaMailSenderImpl();
mailSender.setHost("111.222.33.44");

// 메일 내용을 작성한다
SimpleMailMessage msg = new SimpleMailMessage();
msg.setFrom("aaa@bbb.co.kr");
msg.setTo(new String[] {"ccc@ddd.co.kr", "eee@fff.co.kr"});
msg.setSubject("제목이 이러저러합니다");
msg.setText("본문이 어쩌구저쩌구합니다");

try {
mailSender.send(msg);
} catch (MailException ex) {
// 적절히 처리
}

위에서 2, 3행의 메일 발신 클래스 선언은 환경 설정에 해당하므로 스프링의 개념에서는 의존성 주입(dependency injection) 방식으로 처리하는 것이 맞다. 즉,

@Autowired
private JavaMailSender mailSender;

와 같이 외부에서 인스턴스를 생성해 받는 것이 보다 스프링적인 방법이다. 아무튼 이 방법 역시 API 문서설명서를 참고하면 보다 복잡한 기능을 사용할 수 있다. 다음은 첨부 파일을 넣는 경우다.

MimeMessage msg = mailSender.createMimeMessage();
MimeMessageHelper helper = new MimeMessageHelper(msg, true);
helper.setFrom(new InternetAddress("aaa@bbb.co.kr", "김유신"));
helper.setTo(new InternetAddress("ccc@ddd.co.kr", "연개소문"));
helper.setText("본문이 어쩌구저쩌구합니다", true); // true는 HTML 내용인 경우고 false는 평문 내용인 경우다
helper.addAttachment("파일명", new File("파일 경로"));

3. 기타 방법

아파치 커먼스(Apache Commons) 프로젝트 중에 Email 프로젝트를 사용해서 메일을 보낼 수 있다. 이 역시 JavaMail API를 래핑한 것이라 JavaMail 라이브러리는 필수다. 사용 방법은 프로젝트의 설명 문서를 참고하기 바란다. 마지막으로 아파치 커먼스 Net 같은 프로젝트를 활용해서 SMTP 프로토콜을 직접 제어하는 방법도 있다. 이 방법은 위의 방법들보다 훨씬 복잡하지만 SMTP를 거의 직접적으로 제어하는 수준으로 메일을 발신할 수 있으므로 오류 처리라든가 대량 메일 발신 등의 처리에 있어서 개발자 고유의 로직을 적용할 수 있는 장점이 있다. 사용 방법 예시로 자바 파일이 있으므로 참고해볼만 하다.