상세 컨텐츠

본문 제목

JAVA MAIL 패키지

프로그래밍/JAVA

by 라제폰 2009. 1. 23. 16:56

본문

JAVA MAIL 패키지

 

SMTP,   NNTP,   ..서버       ----- ......  ---->   IMAP,  POP3,  메일박스,  NNTP 서버 ....

                 |                                 전송                        |

                 |                                                                |

          Transport 클래스                                         Folder 클래스

                 |   send(Message)                                   | getMessage(int)

            Message 클래스                                        Message 클래스

 

메일 통신 규약에 독립적인 방식으로 메일 클라이언트를 작성할 수 있게 해준다.

 

자바 1.1 표준 확장 패키지  javax.mail 패키지로 제공된다.

JAF ( JAVABeans Activation Framework) 패키지 javax.activation을 사용하여 구현되었으므로 이를 같이 사용하여야 한다.

 

서비스 제공 패키지의 등록과 설정 프로퍼티

 

javax.mail.Session 클래스는 서비스 제공 패키지의 등록과 설정 프로퍼티를 관리한다.

 

★ Session객체의 생성

Session Session.getDefaultInstance(Properties props, Authenticator authenticator)

: 디폴트 세션 객체

Sesson Session.getInstance(Properties props, Authenticator authenticator)

 

★ 서비스 제공 패키지의 등록과 검색

-서비스 제공 패키지를 사용하기 위해서는 해당 메시지 통신규약 이름 (smtp, imap, pop3, nntp, localmbox) 및 구현 클래스 이름등을 미리 등록하여야 한다.

- 다음과 같은 순서로 탐색된 서비스 등록 파일이 찾아지면 자동적으로 등록 하는데 사용된다.

1) 홈디렉토리내의 lib/javamail.providers

2) 클래스 탐색경로상의 META-INF/javamail.providers

3) 클래스 탐색경로상의 META-INF/javamail.default.providers

 

Provider[] getProviders()

: 등록된 서비스 제공 패키지 목록

setProvider(Provider provider) throws NoSuchProviderException

: 프로그램 제어에 의한 서비스 제공 패키지의 등록

Provider getProvider(String protocol) throws NoSuchProviderException

: 주어진 메시지 통신규약 protocol을 지원하는 서비스 제공 패키지.

mail.<protocol>.class 프로퍼티 혹은 등록파일에 의해 지시된 서비스 제공 패키지 mail.<protocol>.class 프로퍼티는 해당 서비스 통신 규약의 등록된 서비스 제공 패키지 대신에 다른 서비스 제공 패키지를 지정하고자 할 때 사용된다.

 

★ Session 클래스의 설정 프로퍼티

- Properties getProperties()

- String getProperty(String name)

: 이 세션에 연관된 설정 프로퍼티 검색

 

- 다음과 같은 프로퍼티를 사용할수 있다.

mail.transport.protocol

: 디폴트 메시지 통신규약 (디폴트는 1번째로 등록된 서비스 제공 패키지가 지원하는 통신규약)

mail.store.protocol

: 디폴트 메시지 저장소 통신규약 ( 디폴트는 1번째로 등록된 서비스 제공 패키지가 지원하는 통신규약)

mail.host 

: 메시지 서버 호스트 ( 디폴트는 지역 호스트)

mail.user 

: 메시지 서버 접속시에 사용될 이름 (디폴트는 user.name 시스템 프로퍼티 값)

mail.<protocol>.host

: 지정된 통신 규약 사용시 사용될 메시지 서버 호스트

mail.<protocol>.user

: 지정된 통신 규약 사용시 메시지 서버 접속시에 사용될 사용자 이름

mail.from

: 현재 사용자의 반송주소 (디폴트는 mail.user값과, mail.host 값을 @로 연결한 문자열

mail.debug

: 디버드 모드 ( 디폴트는 false)

mail.<protocol>.class

: 지정된 통신규약을 구현하는 서비스 제공 패키지의 클래스 이름

.....

 

★ Provider 클래스

서비스 제공 패키지의 정보제공

Provider.Type getType()

: 지원되는 메시지 통신 규약의 유형( Provider.Type.TRANSPORT혹은 Provider.Type.STORE)

String getProtocol()

: 지원되는 메시지 통신 규약 이름

String getClassName()

: 지원되는 메시지 통신 규약을 구현하는 클래스 이름

String getVendor()

: 패키지 제작자

String getVersion()

: 패키지 버전

 

★ 설치방법

선에서 javaMail 패키지와 JavaActivationFrame을 다운로드 받는다.

jaf패키지를 클래스패스에걸고 javaMail.zip파일에서 모든것이 합쳐져있는 mail.jar 를 클래스패스에 건다.

 

import javax.mail.*;
import java.util.*;
import java.io.*;

public class MailProvidersTest {
    public static void main(String[] args) {
        Properties props = new Properties();
        Session session = Session.getDefaultInstance(props, null);
       
        Provider[] providers = session.getProviders();
        for( int i = 0; i < providers.length; i++ ) {
            System.out.println("=== 서비스 제공 패키지 ===");
            System.out.println(
                "유형: " + (providers[i].getType() == Provider.Type.TRANSPORT
                            ? "전송" : "저장소" ));
            System.out.println("통신 규약: " + providers[i].getProtocol());
            System.out.println("구현 클래스: " + providers[i].getClassName());
            System.out.println("제작자: " + providers[i].getVendor());
            System.out.println("버전: " + providers[i].getVersion());
        }
    }

=== 서비스 제공 패키지 ===

유형: 저장소

통신 규약: imap

구현 클래스: com.sun.mail.imap.IMAPStore

제작자: Sun Microsystems, Inc

버전: null

=== 서비스 제공 패키지 ===

유형: 저장소

통신 규약: imap

구현 클래스: com.sun.mail.imap.IMAPStore

제작자: Sun Microsystems, Inc

버전: null

=== 서비스 제공 패키지 ===

유형: 전송

통신 규약: smtp

구현 클래스: com.sun.mail.smtp.SMTPTransport

제작자: Sun Microsystems, Inc

버전: null

=== 서비스 제공 패키지 ===

유형: 저장소

통신 규약: pop3

구현 클래스: com.sun.mail.pop3.POP3Store

제작자: Sun Microsystems, Inc

버전: null

 

!! 기타 다른사항은 /web/의 setvars.bat 와 /web/META-INF/및의 javamail.providers 참고하라

 

MIME (Multipurpose Internet Mail Extension) 메시지 형식

 

다양한 형식 ( 다양한 문자 인코딩의 텍스트, 화상, 음성, 사운드, 동영상 등등)의 메시지를 전송하기 위한 표준형식

주로 SMTP,HTTP 등에서 사용되며, 화일첨부, 화일 업로드등등의 기능을 가능케한다.

 

JavaMail 패키지의 javax.mail.internet 패키지는 MIME 메시지 처리를 위한 API 를 제공한다.

표준문서 RFC822, RFC2047

 

MimeUtility 클래스

 

- 정의된 모든 메소드는 클래스 메소드이다.

 

- String getDefaultJavaCharset()

: 시스템의 디폴트 자바 인코딩이름

 

- String mimeCharset(String charset)

: 자바 문자 인코딩 이름을 MIME 문자 인코딩 (charset) 이름으로 변환

 

- String getEncoding( javax.activation.DataSource ds)

: ds의 컨텐트 타입과 입력 스트림의 아스키 문자여부, 비율에 따라 적절한 7비트 전송 인코딩(content-transfer-encoding) 을 반환

  "7bit","quoted-printable","base64"중의 하나.

  주로 8비트를 처리 못하는 SMTP 서버로 메일을 전송하는 경우 사용되는 전송 인코딩이다.

 

- OutputStream encode(OutputStream os, String encoding) throws MessageException

: 전송 인코딩 encoding에 따라 인코딩해서 출력스트림 os로 출력해주는 출력 스트림 반환

encoding은 "7bit","quoted-pritable","base64","uuencode","8bit","binary" 중 하나

 

- InputStream decode( InputStream is, String encoding) throws MessagingException

: encode 메소드와 반대되는 디코딩을 해준다.

 

- String encodeText(String text, String charset=null, String encoding=null) throws UnsupportedEncodingException

: 메일 헤더(제목등)에 사용되기 위한 7비트 인코딩으로 변환된 스트링

(문자 인코딩과 전송 인코딩 이름이 인코딩된 문자열내 에 포함된다.)

지정된 문자 인코딩 charset과 지정된 전송 인코딩 encoding  ("Q" 혹은 "B"으로 변환한다. charset이 null이면 시스템의 디폴트 인코딩이 사용되고 encoding이 null이면 아스키 문자의 비율에 따라 적절한 전송 인코딩이 시작된다.

 

- String decodeText(String etext) throws UnsupportedEncodingException

 

- String encodWord(String word) throws UnsupportedEncodingException

 

- String encodWord(String word, String charset, String encoding) throws UnsupportedEncodingException

 

- String decodeWord(String eword) throws ParseException, UnsupportedEncodingException

 

- String quote(Sring word, Sring specials)

 

JDK1.2에서도 올바른 한글 MIME charset 이름인 "euc-kr"이 디폴트로 사용하기 위해서는 다음을 mail.jar 파일내의 META-INF/javamail.charset.map 파일에 추가시킨다.

MS949                 euc-kr

5601                    euc-kr

 

import javax.mail.internet.*;
import java.io.*;

public class MimeUtilityTest {
    public static void main(String[] args) throws UnsupportedEncodingException,
                                                         javax.mail.MessagingException, IOException {
        if (args.length == 0) {
            displayEncoding();           
            return;
        }
        if (args[0].equals("-encode")) {
            OutputStream encoder = MimeUtility.encode(System.out, args[1]);
            for( int b; (b = System.in.read()) != -1; )
                encoder.write(b);
            encoder.close();
        } else if (args[0].equals("-decode")) {
            InputStream decoder = MimeUtility.decode(System.in, args[1]);
            for( int b; (b = decoder.read()) != -1; )
                System.out.write(b);
            decoder.close();
        } else if (args[0].equals("-encodeText")) {
            System.out.println( MimeUtility.encodeText(
                args[1], args.length <= 2 ? null : args[2],
                args.length <= 3 ? null : args[3]) );
        } else if (args[0].equals("-decodeText")) {
            System.out.println( MimeUtility.decodeText(args[1]) );
        }
    }

    static void displayEncoding() {
        System.out.println("디폴트 자바 인코딩: " + MimeUtility.getDefaultJavaCharset());
        System.out.println("디폴트 MIME 인코딩: " // euc-kr 이 나와야 하는데
                           + MimeUtility.mimeCharset( MimeUtility.getDefaultJavaCharset()));
        System.out.println("EUC_KR의 MIME 인코딩: "
                           + MimeUtility.mimeCharset("EUC_KR"));
        System.out.println("euc-kr의 자바 인코딩: "
                           + MimeUtility.javaCharset("euc-kr"));
        System.out.println("utf-8의 자바 인코딩: "
                           + MimeUtility.javaCharset("utf-8"));
    }
}

java MimeUtilityTest

java MimeUtilityTest -encoding quoted-printable 하고나서 자바 java 입력

java MimeUtilityTest -encoding base64 하고나서 자바 java 입력

java MimeUtilityTest -encoding uuencode 하고나서 자바 java 입력

java MimeUtilityTest -encoding quoted-printable 하고나서 자바 java 입력

java MimeUtilityTest -encodingText  "자바 java" euc-kr=?euc-kr?Q?=CO=DA=B9=D9_java?=

 

메시지 주소

 

Address 클래스

        |

        + -- InternetAddress 클래스

        + -- NewAddress

 

★  Address 클래스 ( 메시지 송수신 주소)

String getType()

: 주소의 유형. InetAddress 클래스의 경우 "rfc822", NewsAddress 클래스의 경우 "news"

 

★ InternetAddress 클래스

RFC 822 주소 ( 인터넷 전자 메일 주소 )

new InternetAddress()

new InternetAddress( String address ) throws AddressException

new InternetAddress( String address, String personal ) throws UnsupportedEncodingException

InternetAddress[] InternetAddress.parse(String s, boolean strict=true)throws AddressException

: 콤마로 구분된 전자 메일 주소 리스트로 부터 생성, strict가 false이면ㄴ, 공백문자도 주소들을 구분

InternetAddress[] InternetAddress.getLocalAddress(Session session)

: "mail.from","mail.user","mail.host","user.name" 등의 프로퍼티 값으로 부터 현재사용자의 전자 메일주소 생성

String address

String personal ( throws UnsupportedEncodingException)

: 전자 메일 주소의 소유자 이름. 이름에 비아스키 문자가 포함되면 디폴트 인코딩으로 변환한다.

setPersonal ( String name, String charset) throws UnsupportedEncodingException)

String InternetAddress.toString(Address[] addresses)

String InternetAddress.toString(Address[] addresses, int used)

: 콤마로 구분된 메일 주소 리스트 반환, 디코딩 하지 않는다.

 

★ NewsAddress 클래스

RFC1036 인터넷 뉴스 그룹 주소

new NewsAddress()

new NewsAddress(String newsgroup)

new NewsAddress(String newsgroup, String host)

NewsAddress[] NewsAddress.parse(String newsgroups) throws AddressException

: 콤마로 구분된 뉴스 그룹 주소 목록으로 부터 생성

String newsgroup

: 뉴스그룹이름

String host

: 뉴스서버

String NewsAddress.toString(Address[] address)

: 뉴스 그룹주소 목록을 콤마로 구분된 문자열로 반환

 

import javax.mail.*;
import javax.mail.internet.*;
import java.util.*;

public class AddressTest {
    public static void main(String[] args) throws Exception {
        System.out.println(new InternetAddress("gdhong@host.com"));
        System.out.println(new InternetAddress("gdhong@host.com", "홍길동", "euc-kr"));
        Properties props = new Properties();
        props.put("mail.from", "me@myhost.com");
        Session session = Session.getDefaultInstance(props, null);
        System.out.println(InternetAddress.getLocalAddress(session));

        System.out.println(new NewsAddress("han.comp.lang.java"));
        System.out.println(new NewsAddress("han.comp.lang.java", "usenet.seri.re.kr"));
    }
}

gdhong@host.com

=?euc-kr?B?yKux5rW/?= <gdhong@host.com>

me@myhost.com

han.comp.lang.java

han.comp.lang.java

 

메시지 헤더와 몸체

 

part 인터페이스

       |

MimePart 인터페이스

       |

Multipart 클래스

       |

MimeMultipart 클래스

 

거의 모든 메소드가 throws MessagingException

메시지 형식정보 (헤더)와 메시지 내용으로 이루어질 수 있다.

 

★ Part 인터페이스

 

- 메시지 혹은 부분 메시지 객체의 인터페이스

- 메시지 형식 정보 (헤더)와 메시지 내용으로 나뉘어 진다.

 

setHeader(String headerName, String headerValue)

: 주어진 헤더 이름과 값의 헤더설정, MIME 메시지 헤더의 경우, 아스키 문자만 허용되므로 적절히 인코드 해야 한다.

String[] getHeader(String headerName)

: 이 헤더 이름으로 설정된 모든 헤더값. 필요한 경우 헤더 값을 디코딩 한다.

addHeader(String headerName, StrngHeaderValue)

removeHeader(String headerName)

Enumeration getAllHeaders()

Enumeration getMatchingHeaders(String [] headerNames)

Enumeration getNonMatchingHeaders(String [] headerNames)

: 해당 메시지 헤더를 Header객체의 Enumeration으로 반환

String getContentType()

: 메시지 내용의 형식 (MIME 메시지의 경우, "Content-Type" 헤더값). 알수없는 경우 null

boolean isMimeType(String mimeType)

: 이 메시지 내용 형식이 주어진 MIME 내용 형식 mimetype이면 true

int getSize()

: 메시지 내용의 바이트 수 . 알수없는 경우에는 -1

int getLineCount()

: 메시지 내용의 행 수 . 알수없는 경우에는 -1

String disposition

: 이 메시지의 내용을 사용자에게 보여주기 위한 배치방식. "Content-Disposition" 헤더값

ATTACHMENT 혹은 INLINE

String fileName

: 이 메시지의 내용을 설명정보 "Content-Description" 헤더값

setText(String text)

: text를 "text/plain" MIME 내용 형식의 메시지 내용으로 설정.

setContent(Multipart mp)

: mp를 이 메시지의 내용으로 설정

setContent(Object obj, String type)

: 객체 obj를 이 메시지 내용으로 설정. obj를 메시지 내용형식 type에 따라 변환해줄 DataContentHandler 클래스가 등록되어 있어야 한다.

writeTo(OuputStream os) throws IOException

: 이 메시지를 실제로 전송될 바이트 배열로 변환하여 출력한다.

InputStream getInputStream() throws IOException

: 이 메시지 내용을 읽어들이기 위한 입력 스트림. 사용된 메일 인코딩에 따라 디코딩해준다.

Object getContent() throws IOException

: 메시지 내용 형식에 따라 메시지 내용을 담는 적절한 자료형의 자바 객체 반환. 가령 "text/plain" MIME 내용형식의 경우에는 String, "multipart" MIME 내용형식의 경우에는 Multipart등등

이외의 MIME형식의 경우에는 적절한 DataContentHandler가 등록되어 있어야 한다.

javax.activation.DataHandelr dataHandler

: 메시지 내용을 처리하는데 사용되는 핸들러

 

★ MimePart 인터페이스

 

MIME(RFC 2045) 표준 형식의 메시지 혹은 부분 메시지 객체의 인터페이스

RFC 822 및 MIME 헤더는 아스키 문자만을 표현해야 하므로, 한글등의 문자는 특별한 인코딩을 사용하여 변환된다.

 

String getHeader(String headerName, String delimiter)

: 주어진 이름의 모든 헤더값을 디코딩 하지 않고 delimiter로 구분한 문자열로 반환 delimiter가 null이면 1번째 값만 반환

addHeaderLine(String Line)

: RFC 822 헤더 추가

Enumeration getAllHeaderLines()

Enumeration getMatchingHeaderLines(String[] names)

Enumeration getNoMatchingHeaderLines(String[] names)

String getEncoding()

: 이 메시지의 전송 인코딩. "Content-Transfer-Encodign" 헤더값

String [] contentLanguage

: "Content-Language" 헤더값

String getContentID()

: "Content-ID" 헤더값

String contentMD5

: "content-MD5" 헤더값

setText(String text)

: text를 "text/plain" MIME 내용 형식의 메시지 내용으로 설정.

text가 비 아스키문자를 포함하면 디폴트 문자 인코딩으로 변환한다.

setText(String text, String charset)

: text를 "text/plain" MIME 내용 형식의 메시지 내용으로 설정. charset은 text를 바이트 배열로 변환하기 위한 인코딩이고, MIME 헤더의 "charset" 매개변수값으로 설정된다.

 

★ Multipart 클래스

여러개의 메시지 부분으로 이루어진 메시지 몸체를 나타내는 객체

 

Part parent

: 이 메시지 몸체를 포함하는 바깥 메시지 부분

String getContentType()

int getCount()

: 포함된 메시지 부분(BodyPart)갯수

addBodyPart(BodyPart part)

addBodyPart(BodyPart part, int index)

boolean removeBodyart(BodyPart part)

removeBodyPart( int index)

BodyPart getBodyPart(int index)

writeTo(OutputStream os) throws IOException

protected setMultipartDataSource(MultipartDataSource mp)

 

★ MimeMultipart 클래스

 

new MimeMultipart()

: MIME 메시지 내용형식은 "multipart/mixed" 로 설정되고, 포함된 메시지 부분들을 구분 시키기 위한 경계 스트링이 생성되어 내용 형식 헤더의 "boundary" 매개변수 값으로 사용된다.

new MimeMultipart(String subtype)

: 부형식(subtype)이 subtype인 MIME 메시지 내요혁식 "multipart" 로 설정된다.

new MimeMultipart(javax.activation.DataSource ds)

setSubType(Strng subtype)

BodyPart getBodyPart(String CID)

 

★ BodyPart 클래스 extends BodyPart implements MimePart

다른 메시지내에 포함된 부분 MIME 메시지

new MimeBodyPart()

new MimeBodyPart(InputStream is)

: 입력 스트림으로 부터 MIME자료를 읽어들여 파싱한다.

new MimeBodyPart(InternetHeaders headers, byte[] content)

: MIME 헤더와 자료 내용으로 부터 MIME 메시지 생성

 

메시지

 

Message 클래스

        |

MimeMessage 클래스

 

대부분의 메소드가 throws MessagingException

Message 클래스 implements Part

- (부분 메시지가 아닌) 완전한 메시지

- 메시지는 헤더, 내용, 속성, 폴더내에서의 정보(플래그, 일련번호 등) 로 이루어 진다.

- setFrom()

: 이 메시지의 From 속성설정. 설정되는 값은 "mail.user" 설정 프로퍼티 혹은 "user.name" 시스템 프로퍼티 값이다.

- addFrom(Address[] addresses)

- Address[] getFrom()

: 메시지 송신 주소("From" 속성 값) 경우에 따라서는 실제 송신 주소와 다를수 있다.

- Address[] replyTo

: 메시지 반송 주소(MIME 메시지의 경우 "Reply-To"헤더값) 송신 주소와 다른 반송주소로 메시지를 반송받기 위한 경우 사용

- setRecipient(Message.RecipientType type, Adress address)

- setRecipients(Message.RecipientType type, Adress[] addresses)

: 이 메시지의 수신 종류 type의 수신주소 설정.

type은 Message.RecipientType.TO, Message.RecipientType.CC, Message.RecipientType.BCC, MimeMessage.RecipientType.NEWSGROUPS 중하나

- addRecipient( Message.RecipientType type, Address address)

- addRecipients( Message.RecipientType type, Address[] addresses)

- Address[] getAllRecipients()

: 이 메시지의 모든 수신 주소 ("TO","CC","BCC"등)

- Address[] getRecipients(Message.RecipientType type)

: 이 메시지의 모든 주어진 형식의 수신주소

- String subject

: 메시지 제목 (MIME 메시지의 경우, "subject" 헤더값)

- Date sentDate

: 메시지 송신시각 (MIME 메시지의 경우 "Date" 헤더값)

- Date getReceivedDate()

: 메시지 수신시각

- Folder getFolder()

: 이메시지가 저장되어 잇는 폴더

- int messageNumber leftrightarrow

: 폴더내에서의 메시지 일련번호

- setFlags(Flags.Flag flag, boolean set)

: flag는 다음중 하나

( Flags.Falg.RECENT : 새로 도착한 메시지임

Flags.Falg.SEEN : 이 메시지 내용을 읽었음

Flags.Falg.ANSWERED : 응답메시지를 전송하였음

Flags.Falg.DELETED : 삭제 표시 되었음

Flags.Falg.FLAGGED

Flags.Falg.DRAFT

Flags.Falg.USER )

- Flags getFlags()

- isSet(Flags.Flag flag)

- boolean isExpunged()

: 이 메시지의 폴더내에서 삭제 예정 표시 여부

Message reply(boolean replyToAll)

: 이 메시지의 응답메시지 생성. 메시지 헤더와 속성이 적절히 설정된다.

replyToAll이 true이면 이 메시지의 모든 수신 주소를 응답메시지의 수신 주소로 한다.

- saveChanges()

: 이 메시지의 변경 사항을 메시지 저장소로 저장한다. 서비스 제공 패키지에 따라 즉시 변경되거나 폴더가 닫힐때 저장된다.

- boolean match(SearchTerm term)

: 이 메시지가 탐색기준 term 과 일치하면 true

 

★ MimeMessage 클래스 extends Message implements MimePart

- new MimeMessage (Session session)

- new MimeMessage (Session session, InputStream is)

: 입력 스트림 is를 파싱하여 MIME 메시지 작성

- setContentID(String cid)

: "Content-ID" 헤더 생성

- setDescription(String description, String charset)

: "Content-Description" 헤더값 설정. 헤더 값에 비 아스키 문자가 포함되면 주어진 인코딩을 이용하여 반환

- String getMessageID()
: "Message-ID" 헤더값.

- WriteTo(OutputStream os, String[] ignoreList) throws IOException

: ignoreList의 헤더를 제외하고 바이트 스트림으로 변환하여 출력

 

 

메시지 전송

 

Service 클래스

     |

     + -- Transport 클래스

     + -- Store 클래스

 

★ Session 클래스의 Transport 객체 반환 메소드

- Transport getTransport() throws NoSuchProviderException

: "mail.transport.protocol" 프로퍼티로 지정된 메시지 전송 통신 규약을 처리하는 객체 반환

- Trnasport getTransport(String protocol) throws NoSuchProviderException

: 지정된 메시지 전송 통신규약을 처리하는 객체 반환

- Trnasport getTransport(URLName url) throws NoSuchProviderException

: url이 지시하는 메시지 전송 통신 규약을 처리하는 객체 반환

- Transport getTransport(Provider provider) throws NoSuchProviderException

: 서비스 제공 패키지가 제공하는 메시지 전송 통신 규약을 처리하는 객체 반환

- Transport getTransport(Address address) throws NoSuchProviderException

: 지정된 주소로 메시지를 전송해 주는 객체 반환

 

★  Service 클래스

- connect() throws MessagingException

- connect(String host, String user, String password) throws MessagingException

- connect(String host, int port, String user, String password) throws MessagingException

- URLName getURLName()

- boolean isConnected()

- close() throws MessagingException

- addConnectionListener( ConnectionListender l)

- removeConnectionListener( ConnectionListender l)

 

★ javax.mail.Transport 클래스

- new Transport(Session session, URLName urlname)

- Transport.send(Message msg) throws MessagingException

: 메시시 msg를 msj내의 모든 수신 주소로 전송한다. 전송하기 전에 msg의 saveChanges() 메소드를 호출한다.

- sendMessage(Message msg, Address[] addresses) throws MessagingException

: 메시지 msg를 지정된수신 주소로 전송한다. 송신 상태를 알려주는 TransportEvent가 등록된 이벤트 처리기로 전달된다.

- addTransportListener(TransportListener l)

- removeTransportListener(TransportListener l)

: 이벤트 처리기 등록 , 등록 취소

 

import javax.mail.*;
import javax.mail.internet.*;
import java.util.*;
import java.io.*;

public class SimpleMailSend {
    public static void main(String[] args) throws Exception {
        if (args.length != 3) {
            System.out.println("사용법: java SimpleMailSend" + "<to><from><smtp server>");
            System.exit(1);
        }
       
        String to = args[0];
        String from = args[1];
        String host = args[2];

        Properties props = new Properties();
        props.put("mail.smtp.host", host);

        Session session = Session.getDefaultInstance(props, null);
       
        Message msg = new MimeMessage(session);
        msg.setFrom(new InternetAddress(from));
        InternetAddress[] address = { new InternetAddress(to) };
        msg.setRecipients(Message.RecipientType.TO, address);
        msg.setSubject("Simple Mail Send 테스트");
           
        String msgBody = "";
        BufferedReader in
            = new BufferedReader(new InputStreamReader(System.in));
        for( String line; (line = in.readLine()) != null; ) {
            msgBody += line + '\n';
        }
        msg.setText(msgBody);
           
        Transport.send(msg);
    }
}

C:\111>java SimpleMailSend equaless@unitel.co.kr msj@master.com tksun.aiit.or.kr

java Mail 1.1을 테스트 하기위한 메일입니다.
Exception in thread "main" javax.mail.SendFailedException: Sending failed;
  nested exception is:
        javax.mail.MessagingException: 501 5.0.0 Invalid domain name

        at javax.mail.Transport.send0(Transport.java:219)
        at javax.mail.Transport.send(Transport.java:81)
        at SimpleMailSend.main(SimpleMailSend.java:42)

MIME 메시지 전송 및 파싱

 

HTML 문서, 이미지, 사운드등 다양한 형식의 메시지를 MIME 형식으로 전송하고, 수신받은 메시지를 파싱할수 있다.

자바 메일 패키지는 메시지의 내용과 형식의 처리를 JAF에 의존한다.

 

다양한 형식의 여러 메시지를 MIME 형식 "multipart" 로 전송한다.

import javax.mail.*;
import javax.mail.internet.*;
import javax.activation.*;
import java.util.*;
import java.io.*;

public class MimeMessageSend {
    public static void main(String[] args) throws Exception {
        if (args.length != 3) {
            System.out.println("사용법: java MimeMessageSend"
                               + " <to> <from> <smtp server>");
            System.exit(1);
        }
       
        String to = args[0];
        String from = args[1];
        String host = args[2];

        Properties props = new Properties();
        props.put("mail.smtp.host", host);
        props.put("mail.nntp.host", "usenet.seri.re.kr");

        Session session = Session.getDefaultInstance(props, null);
       
        Message msg = new MimeMessage(session);
        msg.setFrom(new InternetAddress(from));
        Address[] address = { new InternetAddress(to) };
        msg.setRecipients(Message.RecipientType.TO, address);
        msg.setSubject("Mime Message Send 테스트");
           
        Multipart multipart = new MimeMultipart();

        // 일반 텍스트
        MimeBodyPart part1 = new MimeBodyPart();
        part1.setText("1번째 줄\n2번째 줄\n");
        multipart.addBodyPart(part1);

        // 임의의 MIME 형식 (HTML 문서)
        MimeBodyPart part2 = new MimeBodyPart();
        part2.setDataHandler(new DataHandler(
            new ByteArrayDataSource(
                "<html><h1>HTML 메일</h1></html>\n".getBytes(),
                "text/html; charset=euc-kr", null)));
        multipart.addBodyPart(part2);

        // 임의의 MIME 형식 (이미지)
        MimeBodyPart part3 = new MimeBodyPart();
        FileInputStream file = new FileInputStream("rose.jpg");
        part3.setDataHandler(new DataHandler(
            new ByteArrayDataSource(file, "image/jpeg", null)));
        file.close();
        multipart.addBodyPart(part3);

        // 첨부 화일 (attachment)
        MimeBodyPart part4 = new MimeBodyPart();
        FileDataSource fileSource = new FileDataSource("rose.jpg");
        part4.setDataHandler(new DataHandler(fileSource));
        part4.setFileName("rose.jpg");
        multipart.addBodyPart(part4);

        // 화일 (inline)
        MimeBodyPart part5 = new MimeBodyPart();
        part5.setDataHandler(new DataHandler(fileSource));
        part5.setFileName("rose.jpg");
        part5.setDisposition(Part.INLINE);
        multipart.addBodyPart(part5);

        msg.setContent(multipart);
        Transport.send(msg);
    }
}

class ByteArrayDataSource implements DataSource {
    private byte[] data;
    private String type;
    private String name;

    public ByteArrayDataSource(InputStream is, String type, String name)
        throws IOException {
        ByteArrayOutputStream os = new ByteArrayOutputStream();
        byte[] buf = new byte[1024];
        for ( int count; (count = is.read(buf)) != -1; )
            os.write(buf, 0, count);
        data = os.toByteArray();
        this.type = type;
        this.name = name;
    }

    public ByteArrayDataSource(byte[] data, String type, String name) {
        this.data = data;
        this.type = type;
        this.name = name;
    }

    public InputStream getInputStream() throws IOException {
        if (data == null)
            throw new IOException();
        return new ByteArrayInputStream(data);
    }

    public OutputStream getOutputStream() throws IOException {
        throw new IOException();
    }

    public String getContentType() {
        return type;
    }

    public String getName() {
        return name;
    }
}

 

import javax.mail.*;
import javax.mail.internet.*;
import java.util.*;
import java.io.*;

public class MimeMessagePrint {
    public static void main(String[] args) throws Exception {
        Properties props = new Properties();
        Session session = Session.getDefaultInstance(props, null);
       
        FileInputStream data = new FileInputStream(args[0]);
        MimeMessage msg = new MimeMessage(session, data);

        System.out.println("=== 메시지 속성 및 플래그 ===");
        System.out.println("getMessageID(): " + msg.getMessageID());
        System.out.println("getFrom(): " + toString(msg.getFrom()));
        System.out.println("getReplyTo(): " + toString(msg.getReplyTo()));
        System.out.println(
            "To: " + toString(msg.getRecipients(Message.RecipientType.TO)));
        System.out.println(
            "CC: " + toString(msg.getRecipients(Message.RecipientType.CC)));
        System.out.println(
            "BCC: " + toString(msg.getRecipients(Message.RecipientType.BCC)));
        System.out.println(
            "News Group: " + toString(msg.getRecipients(
                MimeMessage.RecipientType.NEWSGROUPS)));

        System.out.println("getSubject(): " + msg.getSubject());
        System.out.println("getSentDate(): " + msg.getSentDate());
        System.out.println("getMessageNumber(): "
                           + msg.getMessageNumber());
        System.out.println("getReceivedDate(): " + msg.getReceivedDate());
        System.out.println("isSet(Flags.Flag.RECENT): "
                           + msg.isSet(Flags.Flag.RECENT));
        System.out.println("isSet(Flags.Flag.SEEN): "
                           + msg.isSet(Flags.Flag.SEEN));
        System.out.println("isSet(Flags.Flag.ANSWERED): "
                           + msg.isSet(Flags.Flag.ANSWERED));
        System.out.println("isSet(Flags.Flag.DELETED): "
                           + msg.isSet(Flags.Flag.DELETED));

        printPart(msg);
    }

    static String toString(Address[] addrs) {
        if ( addrs == null )
            return null;
        String result = "";
        for( int i = 0; i < addrs.length; i++ )
            result += addrs[i] + ", ";
        return result;
    }

    static void printPart(Part part) throws IOException, MessagingException {
        System.out.println("=== 메시지 헤더 ===");
        Enumeration headers = part.getAllHeaders();
        while( headers.hasMoreElements() ) {
            Header header = (Header) headers.nextElement();
            System.out.println( header.getName() + ": " + header.getValue() );
        }

        System.out.println("=== 메시지 내용 ===");

        Object content = part.getContent();
        if (content instanceof String) {
            System.out.println(content);
        } else if (content instanceof Multipart) {
            Multipart multipart = (Multipart) content;
            int count = multipart.getCount();
            for (int i = 0; i < count; i++)
                printPart(multipart.getBodyPart(i));
        } else if (content instanceof InputStream) {
            InputStream is = (InputStream) content;
            System.out.print("저장 화일 이름(" + part.getFileName() + ")? ");
            String fileName = stdin.readLine();
            if ( fileName.equals("") )
                fileName = part.getFileName();
            FileOutputStream file = new FileOutputStream(fileName);
            byte[] buf = new byte[1024];
            for ( int count; (count = is.read(buf)) != -1; )
                file.write(buf, 0, count);
            file.close();
        }
    }

    static BufferedReader stdin
        = new BufferedReader(new InputStreamReader(System.in));
}

java MimeMessageSend he@hishost.com me@mehost.com myserver.com

수신받은 메시지를 "test.mail"로 저장한 후,내용을 파싱하여 조사한다.

java MimeMessagePrint test.mail

 

 

메시지 저장소 접근

 

★ Session 클래스의 Store 객체 반환 메소드

- Store getStore() throws NoSuchProviderException

: "mail.store.protocol" 프로퍼티로 지정된 메시지 저장소 통신 규약을 처리하는 객체반환

- Store getStore(String protocol) throws NoSuchProviderException

: 지정된 메시지 저장소 통신 규약을 처리하는 객체반환

- Store getStore(URLName url) throws NoSuchProviderException

: 서비스 제공 패키지가 제공하는 메시지 저장소 통신 규약을 처리하는 객체 반환

- Folder getFolder(URLName url) throws MessagingException

: url이 지시하는 메시지 저장소 통신규약 및 해당 메시지 저장소에 접근하는 객체반환

 

★ Session 클래스의 암호 사용 인증 관련 메소드

- 메시지 통신 규약시에 요구되는 사용자 이름 및 암호의 처리

- 사용자로 부터 입력을 요구하고 입력된 데이타를 재사용하기 위해 서비스 제공 패키지에 의해 사용된다.

- setPasswordAuthentication(URLName url, PasswordAuthentication pw)

- PasswordAuthentication getPasswordAuthentication (URLName url)

- PasswordAuthentication requestPasswordAuthentication (InetAddress add, int port, String protocol, String prompt, String defaultUserName)

 

★ javax.mail.Store 클래스

- 메시지 저장소(IMAP, POP3, NNTP 서버, 메일박스 등등)접근

- 메시지 저장소는 여러 메시지를 담는 여러 폴더를 관리한다.

- Folder getDefaultFolder() throws MessagingException

- Folder getFolder(String name) throws MessagingException

- addStoreListener(StoreListener l)

- removeStoreListener(StoreListener l)

- addFolderListener(FolderListener l)

- removeFolderListener(FolderListener l)

 

★ javax.mail.Folder 클래스

- 여러 메시지 혹은 하위 폴더를 포함하는 폴더

- String getName()

: 폴더이름 "INBOX"는 주 폴더이름이다.

- String getFullName()

- URLName getURLName() throws MessagingException

- Store getStore()

- Folder getParent() throws MessaginException

- boolean exists() throws MessagingException

- Folder[] list() throws MessagingException

- Folder[] list(Strng pattern) throws MessagingException

: 폴더이름 패턴(특수기호 *,%를 사용)과 일치하는 폴더목록

- Folder[] listSubscribed() throws MessagingException

- Folder[] listSubscribed(String pattern) throws MessagingException

- char getSeparator() throws MessagingException

- int getType() throws MessagingException

: HOLDS_MESSAGES혹은 HOLDS-FOLDERS

- boolean create(int type) throws MessagingException

- Folder getFolder(String name) throws MessagingException

- boolean subsribed

- boolean delete(boolean recurse) throws MessagingException

- boolean renameTo(Folder f) throws MessagingException

- open ( int mode ) throws MessagingException

- boolean isOpen()

- int getMode()

: READ_ONLY, READ_WRITE

- close(boolean expunge) throws MessagingException

: expunge가 true이면, 삭제 표시된 모든 메시지 삭제

- Flags getPermanentFlags()

- int getMessageCount() throws MessagingException

- boolean hasNewMessage() throws MessagingException

- int getNewMessageCount() throws MessagingException

- int getUnreadMessageCount() throws MessagingException

- Message getMessage(int msgnum) throws MessagingException

- Message[] getMessages() throws MessagingException

- Message[] getMessages(int start, int end) throws MessagingException

- Message[] getMessages(int[] msgnums) throws MessagingException

- appendMessages (Message[] msgs) throws MessagingException

- fetch(Message[] msgs, FetchProfile fp) throws MessagingException

- setFlags(Message[] msgs, Flags flag, boolean value) throws MessagingException

- setFlags ( int start, int end, Flags flag, boolean value) throws MessagingException

- setFlags(int[] msgnums, Flags flag, boolean value) throws MessagingException

- copyMessages(Message[] msgs, Folder folder) throws MessagingException

- Message[] expunge() throws MessagingException

: 삭제표시된 메시지 삭제

- Message[] search(SearchTerm term) throws MessagingException

- Message[] search(SearchTerm tern, Message[] msgs) throws MessagingException

- addMessageCountListener ( MessageCountListener l)

- removeMessageCountListener ( MessageCountListener l)

- addMessageChangedListener ( MessageCountListener l)

- removeMessageChangedListener ( MessageCountListener l)

 

테스트 프로그램

web/StoreTest.java

프로그램을 실행하여 '연결' 보턴을 누룬후 , 메시지 통신규약, 서버, 사용자 이름 , 암호입력한다.


관련글 더보기