2013년 6월 20일 목요일

JAVA MAIL API 와 활용예제

JAVA MAIL API 와 활용예제

자바를 사용해 이메일 전송해보자.
먼저 이메일을 전송하기위해 사용되는 JAVA MAIL API에 대하여 개략전인 개념을 살펴보고
E-Mail 서버로 사용될 수 있는 JAMES를 기반으로한 이메일 전송 예제를 실행해보는 걸로 이어 가겠다.

JAVA Mail API
기존에 자바에서 메일과 관련된 프레임워크를 개발하기 위해서 개발자들은 스스로 전체적인 메일 시스템을 설계하고 구현해야만 했다. 하지만, Java Mail API가 발표되면서, 개발자들은 메일 시스템의 프레임워크를 설계하는 데 고민할 필요가 없어졌으며, 또한 Java Mail API와 함께 제공되는 클래스들(SMTP, POP3, IMAP을 구현하였다)을 사용하여 매우 손쉽게 메일을 주고 받는 시스템을 구축할 수 있게 되었다.

이 글에서는 Java Mail API가 무엇이며, 어떻게 구성되어 있는 지 살펴볼 것이며, 다음 기사에서는 Java Mail API를 이용하여 간단한 웹 기반의 메일 시스템을 구현해볼 것이다.

Java Mail API의 주요 목적은 개발자들이 손쉽게 어플리케이션의 메일 기능을 추가하고 또한 정교한 사용자 인터페이스를 생성할 수 있도록 하는 것이다. Java Mail API는 Message, Transport, Session과 같이 메일의 공통적인 기능과 프로토콜을 추상화한 클래스를 포함하고 있으며, 또한 자바 기반이기 때문에 자바 플랫폼에서 제공하는 다양한 API를 사용할 수 있다. 다음 그림은 Java Mail API의 전체적인 구조를 보여주고 있다.


위 그림을 보면 가장 상위에 메일 시스템을 사용하는 어플리케이션 위치하는 것을 알 수 있다. 이 어플리케이션은 Java Mail의 추상 클래스를 통해서 실제 구현 클래스 계층에 접근하게 된다. 구현 클래스 계층은 하부에 있는 실제 이메일 시스템 구현 계층과 상호작용한다.메일의 컨텐츠와 관련된 데이터는 JAF(JavaBean Activation Framework)를 사용하여 표현할 수 있다. 일반적으로 Java Mail API를 사용하는 어플리케이션은 다양한 포맷을 제공하기 위해 JAF를 통해 메일 메시지의 컨텐츠를 생성한다.

Java Mail API는 다음과 같은 기능을 수행하는 것을 기본 목적으로 한다.
  • 헤더와 데이터로 구성된 메일 메시지를 생성한다. Java Mail은 메일 메시지를 정의하기 위해 Message 클래스를 사용한다.
  • Session 객체를 생성한다. 이 객체는 사용자를 인증하고 메시지 저장과 전송에 대한 접근을 제어한다.
  • 메시지를 전송한다.
  • 메시지 저장소로부터 메시지를 읽어온다.
  • 읽은 메시지에 명령어를 수행한다. '보기'나 '출력' 같은 명령어는 JAF를 인식하는 자바빈에서 구현하도록 하고 있다.
일반적으로 이러한 기능은 메일 클라이언트가 기본적으로 제공하는 것들이다. 전체 프레임워크를 그림으로 나타내면 다음과 같다.



JAMES
JAMES 를 소개하기전 아래그림을 먼저 살펴보자.
클라이언트(즉 내컴퓨터) 에서 자바로 이메일을 작성 하여 전송하게 되면 SMTP프로토콜을 이용하여 전달되어지는데 이 SMTP프로토콜을 해석 할 수 있는 중간 서버가 필요하다.
그림에서 'Your ISP's Mail Server' 라 써있는 부분이 이에 해당하는데 해당 서버는 앞으로 소개할 JAMES로 대체 할 수도 있고 Google 의 SMTP서버나 기타 포탈 사이트에서 제공하는 메일서버를 사용 할 수 있다.

JAMES란?
Apache에서 제공하는 Java Apache Mail Enterprise Server 이다.

여기까지는 자바로 메일을 전송하기 위한 배경지식에 대하여 알아보았다. 
이후 부터는 JAMES 서버 셋팅과 JAVA로 구현한 예제프로그램을 살펴보자.

JAMES 설치 및 환경구축

[1단계 : 메일 서버 다운로드]
자바의 메일서버는 아파치에서 제공하는 james(Java Apache Mail Enterprise Server) 
서버를 이용할 수 있다
서버 다운로드 ==> http://james.apache.org

[2단계 : 메일 서버 설치]
설치방법은 간단하다. 다운로드 받은 파일의 압축을 풀면되는데, 주의 할점은 
바탕화면에 압축을 풀면 가동되지 않는다.( 아마도 한글 경로 이름때문인듯 하다.. )
필자의 경우 C:\james-2.3.1 에 위치 시켰다.

[3단계 : 메일 서버 환경 설정]
james 서버의 환경설정은 config.xml 파일로 제어한다.
파일의 경로는 /app/james/SAR-INF 에 있다.
config.xml 을 연후 다음과 같이 수정해준다.
a.사용자의 암호 지정 (설정이 끝나면 이 암호로 서버에 접속할 수 있다.)
<account login="root" password="암호" />

b.메일서버 지정하기
servername 태그안에 자신의 아이피 혹은 호스트명을 적는다.
<servername>127.0.0.1</servername>
c.DNS서버 지정하기
ipconfig/all 로 자신의 DNS서버를 찾아서 다음과 같이 기재한다.
<dnsserver>
   <servers>
      <server>DNS서버 주소</server>
   </servers>
   .... 중략
</dnsserver>

[4단계 : JAMES 실행]
/bin/ 디렉토리의 run.bat 파일을 실행시켜서 인스턴스를 띄운다.

james 서버 접속 및 관리

1단계 : 커맨드창에서 (cmd) 다음과 같이 명령어를 입력하여 텔넷으로 서버에 접속.
C:\>telnet localhost 4555

2단계 : root계정으로 로그인. 
( 아이디 : root / 패스워드 : config.xml 에서 지정한 비밀번호)

3단계 help 라고 입력해보면 james 서버를 제어할 명령어가 출력된다.



JAVA 예제프로그램 작성


이메일 전송을 위한 클래스 : 메일서버 프로퍼티를 받아두는 생성자가 있으며 실제 메일은 전송하는 sendMail 메소드로 구성된다. Google 의 SMTP서버를 사용할때는 계정인증을 통하여 메일을 전송할 수 있기 때문에 내부 클래스로 Authenticator 클래스를 확장한 EmailAuthenticator 클래스를 만들어 사용하고 있다. 

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
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
package a.b.c.email;
 
import java.util.Date;
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 org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
 
 
public class EmailSender {
 
    protected final Log logger = LogFactory.getLog(getClass());
     
    private Properties props;
     
    public EmailSender(Properties props) {
        this.props = props;
    }
     
    public void sendEmail(String from, String to, String subject, String content) {
 
        EmailAuthenticator authenticator = new EmailAuthenticator();
 
        Session session = Session.getInstance(props, authenticator);
         
        try {
            Message msg = new MimeMessage(session);
             
            msg.setFrom(new InternetAddress(from));
            logger.debug(msg.getFrom()[0].toString());
            // Recipients 받는사람
            msg.setRecipients(Message.RecipientType.TO, InternetAddress.parse(to));
            msg.setSubject(subject);
            msg.setContent(content, "text/html; charset=UTF-8");
            msg.setSentDate(new Date());
            Transport.send(msg);
        } catch (MessagingException e) {
 
            e.printStackTrace();
 
        }
 
    }
     
    class EmailAuthenticator extends Authenticator {
 
        private String id;
        private String pw;
 
        public EmailAuthenticator(){
            this.id = "u2warehdm@gmail.com";
            this.pw = "Gmail비밀번호";
        }
         
        public EmailAuthenticator(String id, String pw) {
            this.id = id;
            this.pw = pw;
        }
 
        protected PasswordAuthentication getPasswordAuthentication() {
            return new PasswordAuthentication(id, pw);
        }
 
    }
 
}

테스트 클래스 : JUNIT 을 사용하여 테스트 하고 있으며 james 와 Google의 SMTP서버 사용을 위한 각각의 프로퍼티를 생성하여 EmailSender 에 주입해준 후 메일전송을 테스트한다.

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
32
33
34
package a.b.c.email;
 
import java.util.Properties;
 
import org.junit.Test;
 
public class TestEmail {
 
    @Test
    public void mailSendTest(){
 
        Properties gmailProps = new Properties();
        gmailProps.put("mail.smtp.starttls.enable", "true");
        gmailProps.put("mail.smtp.host", "smtp.gmail.com");
        gmailProps.put("mail.smtp.auth", "true");
        gmailProps.put("mail.smtp.port", "587");
         
        Properties jamesProps = new Properties();
        jamesProps.put("mail.smtp.host", "127.0.0.1");
         
        String from = "s20307@naver.com";
        // 보내는이 메일주소
        String to = "s20307@naver.com,";
        // 받는이 이메일 주소는 반드시 ","로 구분해준다. String to = "받을 이메일 주소1,받을 이메일 주소2";
        String subject = "이메일 발송 테스트";
        String content = "안녕하세요 Java Email 발송 테스트입니다.";
         
        //EmailSender emailSender = new EmailSender(gmailProps);
        EmailSender emailSender = new EmailSender(jamesProps);
        emailSender.sendEmail(from, to, subject, content);
 
    }
     
}
위 예제를 실행하기 위하여 JAVA Mail API 를 사용 해야 한다. 해당 JAR파일을 다운로드 받아 라이브러리에 추가하거나 MAVEN 을 이용하여 POM.XML 에 디펜던시를 정의해주면 된다.
[JAVA Mail API Dependency 정보]
1
2
3
4
5
<dependency>
            <groupid>javax.mail</groupid>
            <artifactid>mail</artifactid>
            <version>1.4.5</version>
        </dependency>

저작자 표시