요즘 자바기술을 이용하여 굉장히 많은 일들이 벌어지고 있다. Mobile쪽을 비롯하여 일반 application 및 대형 Enterprise환경까지 자바가 미치는 범위는 정말 광대하다. 여기서 시작되는 연재는 현재 J2EE(Java 2 Enterprise Edition)의 JavaMail을 다룰 것이다. 이번 연재에서 자바의 역사가 이렇다 저렇다 할수 있는 상황은 아닌것 같다. 이글을 읽는 사람은 OOP(Object Oriented Programming)의 개념을 정확히 알고 있어야 할것이다. J2EE쪽 환경이라면 우선 기본적인 지식을 갖추어야 하지만 본 내용은 소스코드를 복사하여 여러분들의 편집기에 붙여넣고 컴파일한후 실행시켜도 돌아갈수 있게끔 만들었다. 장황한 설명은 하지 않겠다. 이제 interface의 진수를 맛보도록 하자. Content(1부) 자바메일(JavaMail)이란? Windows 2000환경에서 smtp의 세팅법 localhost smtp를 이용한 메일보내기 Major JavaMail API Components/JavaMail Event Model Session/Message/Address Class Authenticator Class Transport Class Store class & Folder class Delete/Reply Message Fowarding Message * Java Mail이란? Sun Microsystems의 J2EE의 하나로 지원하고 있는 package이다. 또한 자바기술기반의 Messaging or Mail 애플리케이션으로 구성되어, 플랫폼 독립적이고 protocol에 독립적인 framework을 제공해주는 MailAPI로 구성되어 있다. MailAPI는 또한 JDK1.1.6 또는 그 이상에서 작동시킬수 있으며, 일반적으로 J2EE 의 일부분으로서 동작한다. Java mail reference에 대한 구현은 core JavaMail packages와 IMAP, POP3, SMTP service provider가 포함되어져 있다. * 어디서 구할수 있는가? 기본적으로 Java Mail을 구현하기 위해서는 J2SDK가 있어야 하는데, 위에서 언급했던바와 마찬가지로 JDK1.1.6이상의 VM이 설치되어야 한다. JDK download http://java.sun.com/products/j2se/ Java Mail download http://java.sun.com/products/javamail/ 또한 Java메일은 Data Content Handling을 하기 위해 JavaBeans Activation Framework이란 것이 필요하다. JAF download http://java.sun.com/beans/glasgow/jaf.html JDK를 설치한후 나머지 java mail API와 jaf는 zip 포맷형태로 다운로드 받으며, 해당 디렉토리에 압축을 풀도록 한다. 이전 Mail 1.1.3에서는 각각의 프로토콜에 관련된 패키지가 따로 설정되어 있어, 각각을 시스템의 classpath에 추가시키도록 한다. 압축을 푼후 classpath에 mail.jar, imap.jar, pop3.jar, smtp.jar와 activation.jar를 추가시키도록 한다. * more info IMAP is defined by RFC2060. For more information, see http://www.imap.org/ SMTP, MIME, POP3 등에 관련된 프로토콜은 http://www.imc.org/에서 해당 프로토콜에 대한 자세한 설명을 하고 있다. * Windows 2000에서의 SMTP설치 이번 편에서는 Windows 2000환경에서 smtp의 세팅법에 대하여 알아보도록 하자 요즘 대다수의 환경은 Windows 2000 Professional이상 혹은 Linux운영체제를 가지고 있을것이다. 이러한 optional하게 SMTP(Simple Mail Transfer Protocol)을 지원하고 있다. 대부분 설치시에 물어보게 되는데, Linux의 경우 전체 설치또는 서버설치를 하게 되면, 해당 시스템 커널에 SMTP daemon이 init시점에 뜨게 된다. inux는 기본 SMTP를 사용하도록 하며, 여기서는 Windows 2000의 환경에서 테스트를 시도해보도록 하자. 우선 Windows 2000의 환경설정인데, Server급같은 경우 인터넷서비스 관리자가 자동으로 운영체제 인스톨시에 설치되게 되는데, Professional같은 경우는 그렇지가 않다. 2000의 설치CD를 이용하여 구성요소 -> 인터넷서비스관리자를 추가하도록 한다. 자. 이제 다 설치가 끝이 났는가? 그러면 시작 - > 설정 -> 제어판 -> 관리도구 -> 인터넷서비스관리자 로 가본다. 그곳으로 들어가면 최상단 Root에 해당 컴퓨터의 이름이 나오게 되고, 하위디렉토리를 보면 기본 FTP 사이트, 기본 WEB 사이트, 기본 SMTP가상서버가 있을것이다. 기본SMTP가상 서버에 마우스를 클릭하여 등록정보로 들어가보도록 한다. Pane에 기본, 액세스, 배달, 메시지, 라우팅, 보안등의 항목이 있을것이다. 그곳에서 액세스를 클릭하면 몇가지 항목이 나오는데 맨 아래쪽에 릴레이제한이란 메뉴가 있다. 릴레이버튼을 클릭하면 가상서버를 통해 릴레이할 컴퓨터를 선택할수 있는데 그곳에 loopback IP Address(127.0.0.1)를 입력하도록 한다. 아래목록만 또는 아래목록만 제외라는 option버튼이 있는데 아래목록만에 체크를 하도록 하고 확인을 누르면 설정이 끝나게 된다. 이 가상서버를 통해서는 Outlook등의 smtp를 localhost로 잡고, 메일을 보낼수 있는 준비가 다 된것이다. 여기까지 다 따라했으리라 본다. 자.. 이제 여러분들은 JDK1.1.6 이상 Java Mail API 1.2가 여러분들 컴퓨터에 세팅되어 있고, localhost의 smtp를 구동시켰다.
우선 중요한 클래스들부터 살펴보도록 하자.
사용자 삽입 이미지
Major Java Mail API Component를 보면 interface와 해당 클래스를 extends받은 클래스들로 정의된다. 최상위 interface Part가 존재하며 javax.mail.internet.MimePart interface가 이 클래스를 extends받아 사용한다. Part 인터페이스는 Message와 BodyPart에 의해 implements되어진다. 또한 MimePart는 MimeMessage와 MimeBodyPart에 의해 implements되어진다. 위의 클래스들을 상속받은 많은 클래스들이 core API를 구성하고 있으며, service provider에 의한 확장이 용이해지는 장점을 가지고 있다. 메시지를 보낼때는 Message클래스와 Transport클래스에 의한 구현을 할수 있으며, 메시지를 받을때는 Store클래스와 Folder클래스를 통하여 해당 시스템의 메일박스(보통 INBOX)를 통해 Message타입의 데이터를 우리 눈으로 볼수 있는 결과가 된다.
사용자 삽입 이미지
위의 형태로 메시지를 전달할수 가 있다. 여러분들이 중요하게 봐야 할 클래스는 Message와 Transport, Store, Folder, Session 클래스들이다. 또한 Data Handling을 위해서는 javax.activation패키지의 클래스들을 유심히 봐야할 것이다. 사실상 메일은 위 클래스의 메소드를 유효적절하게만 활용을 해도 전달 또는 메일시스템을 구축할수 있다. 자 이제 SMTP를 사용하여 간단한 메일을 전송하여 보도록 하자. 일반적으로 arguments값을 외부로부터 입력받아 사용해야 하지만 바쁜 관계로 String의 배열안에 모두 입력한후 처리하였다. 사실 눈여겨 볼부분은 몇줄 안되며 catch블록이하는 Exception을 처리하기 위한 부분이다. 소스코드를 보도록 하자.
import java.util.*; import java.io.*; import javax.mail.*; import javax.mail.internet.*; import javax.activation.*; public class msgsendsample { static String msgText = "This is a message body.\nHere's the second line."; public static void main(String[] args) { // 스트링의 배열값으로 보낼 property값들을 세팅한다. String arg [] ={"ienvyou@orgio.net","ienvyou@javapattern.info", "localhost", "true"}; System.out.println(); String to = arg[0]; // 보낼 사람의 주소이다. String from = arg[1]; // 보내는 사람의 주소이다. String host = arg[2]; // SMTP서버가 돌고 있는 곳의 주소이다. boolean debug = Boolean.valueOf(arg[3]).booleanValue(); // Properties props = new Properties(); props.put("mail.smtp.host", host); // 메일을 보낼때 디버깅코드를 화면에 보여줄지를 세팅한다. if (debug) props.put("mail.debug", arg[3]); Session session = Session.getDefaultInstance(props, null); session.setDebug(debug); // 해당 세션클래스의 디버깅 옵션을 argument값으로 설정한다. try { // create a message /** * MimeMessage는 Message를 extends받고 있으며 메일을 보낼때 필요한 핵심 메소드들을 * abstract method 또는 * general method형태로 가지고 있다. // MimeMessage객체를 생성하여 javax.mail.Message타입에 넣는다 */ Message msg = new MimeMessage(session); . msg.setFrom(new InternetAddress(from)); // 보낼 사람의 주소를 InternetAddress형태의 배열로 변환한다. //(수신자가 여러명될수 있으므로..); InternetAddress[] address = {new InternetAddress(arg[0])}; // 수신인을 Message에 세팅한다. msg.setRecipients(Message.RecipientType.TO, address); msg.setSubject("JavaMail APIs Test"); msg.setSentDate(new Date()); // If the desired charset is known, you can use // setText(text, charset) msg.setText(msgText); // 아래의 static메소드에 의해 메일발송 Transport.send(msg); } catch (MessagingException mex) { System.out.println("\n--Exception handling in msgsendsample.java"); mex.printStackTrace(); System.out.println(); Exception ex = mex; do { if (ex instanceof SendFailedException) { SendFailedException sfex = (SendFailedException)ex; Address[] invalid = sfex.getInvalidAddresses(); if (invalid != null) { System.out.println(" ** Invalid Addresses"); if (invalid != null) { for (int i = 0; i < invalid.length; i++) System.out.println(" " + invalid[i]); } } Address[] validUnsent = sfex.getValidUnsentAddresses(); if (validUnsent != null) { System.out.println(" ** ValidUnsent Addresses"); if (validUnsent != null) { for (int i = 0; i < validUnsent.length; i++) System.out.println(" "+validUnsent[i]); } } Address[] validSent = sfex.getValidSentAddresses(); if (validSent != null) { System.out.println(" ** ValidSent Addresses"); if (validSent != null) { for (int i = 0; i < validSent.length; i++) System.out.println(" "+validSent[i]); } } } System.out.println(); if (ex instanceof MessagingException) ex = ((MessagingException)ex).getNextException(); else ex = null; } while (ex != null); } } private static void usage() { System.out.println("usage: java msgsendsample <to> <from> <smtp> true|false"); } }
위의 코드에서 잘 살펴보아야 할부분은 MimeMessage를 생성한후 정보를 세팅하는 일들이다. setXXX메소들에 의해 세팅되어 지며, Transport클래스의 메소들에 의해 실질적인 network infrastructure를 통해 메일이 발송되어 지게 된다. 유심히 본 사람은 Properties클래스가 존재하는데, 왜 있을까? 라는 궁금증이 생길것이다.. 원래 보는 사람들이 후편을 기다리게 만들어야 만드는 사람도 재미있지 않을까? 다음 시간에는 Properties의 역할과 SMTP가 local에 없을경우(orgio나 chollian같은 곳의 smtp)를 인증을 통하여 사용하고 싶을때의 JavaMail에 대하여 이야기할 것이다..
크리에이티브 커먼즈 라이선스
Creative Commons License
Posted by 때찌1