차근차근/JAVA JSP
javamail
검색어 : mail,smtp,host
지난 시간에는 실제적인 메일 전송은 하지 않고, 로그로만 출력했는데, 찜찜한 관계로 한번 해보도록 하자.
자바 진영에서는 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 클래스를 만들어보자.
001 | package kr.kangwoo.postman.service; |
002 |
003 | import java.io.UnsupportedEncodingException; |
004 | import java.util.Properties; |
005 |
006 | import javax.mail.Authenticator; |
007 | import javax.mail.Message; |
008 | import javax.mail.MessagingException; |
009 | import javax.mail.PasswordAuthentication; |
010 | import javax.mail.Session; |
011 | import javax.mail.Transport; |
012 | import javax.mail.internet.InternetAddress; |
013 | import javax.mail.internet.MimeMessage; |
014 |
015 | import kr.kangwoo.postman.core.MailException; |
016 | import kr.kangwoo.postman.core.MailStatusCode; |
017 | import kr.kangwoo.postman.core.MessageException; |
018 | import kr.kangwoo.util.StringUtils; |
019 |
020 | import org.slf4j.Logger; |
021 | import org.slf4j.LoggerFactory; |
022 |
023 | public class SMTPMailSendManager implements MailSendManager { |
024 |
025 | private Logger logger = LoggerFactory.getLogger(getClass()); |
026 | |
027 | private String protocol = "smtp" ; |
028 | private String type = "text/html; charset=KSC5601" ; |
029 | |
030 | private String userName; |
031 | private String password; |
032 | private String host = "127.0.0.1" ; |
033 | private int port = 25 ; |
034 | private boolean starttlsEnable = false ; |
035 |
036 | public void setUserName(String userName) { |
037 | this .userName = userName; |
038 | } |
039 |
040 | public void setPassword(String password) { |
041 | this .password = password; |
042 | } |
043 |
044 | public void setHost(String host) { |
045 | this .host = host; |
046 | } |
047 |
048 | public void setPort( int port) { |
049 | this .port = port; |
050 | } |
051 |
052 | public void setType(String type) { |
053 | this .type = type; |
054 | } |
055 | |
056 | public void setStarttlsEnable( boolean starttlsEnable) { |
057 | this .starttlsEnable = starttlsEnable; |
058 | } |
059 |
060 | public void send(String toAddress, String toName, String fromAddress, |
061 | String fromName, String subject, String content) throws MessageException { |
062 | logger.debug( "[{}] 메일 발송 시작" , toAddress); |
063 | try { |
064 | Properties props = new Properties(); |
065 | props.put( "mail.transport.protocol" , protocol); |
066 | props.put( "mail.smtp.host" , host); |
067 | props.put( "mail.smtp.port" , String.valueOf(port)); |
068 | |
069 | Authenticator authenticator = null ; |
070 | if (StringUtils.isNotBlank(userName)) { |
071 | props.put( "mail.smtp.auth" , "true" ); |
072 | authenticator = new SMTPAuthenticator(userName, password); |
073 | } |
074 | |
075 | if (starttlsEnable) { |
076 | props.put( "mail.smtp.starttls.enable" , Boolean.toString(starttlsEnable)); |
077 | } |
078 | |
079 | Session session = Session.getInstance(props, authenticator); |
080 |
081 | MimeMessage message = new MimeMessage(session); |
082 | message.setFrom( new InternetAddress(fromAddress, fromName)); |
083 | message.addRecipient(Message.RecipientType.TO, new InternetAddress(toAddress, toName)); |
084 | message.setSubject(subject); |
085 | message.setContent(content, type); |
086 |
087 | Transport.send(message); |
088 | logger.debug( "[{}] 메일 발송 성공" , toAddress); |
089 | } catch (UnsupportedEncodingException e) { |
090 | logger.debug( "[{}] 메일 발송 실패" , toAddress); |
091 | throw new MailException(MailStatusCode.SEND_FAIL, "메일을 발송하는 중 에러가 발생했습니다." , e); |
092 | } catch (MessagingException e) { |
093 | logger.debug( "[{}] 메일 발송 실패" , toAddress); |
094 | throw new MailException(MailStatusCode.SEND_FAIL, "메일을 발송하는 중 에러가 발생했습니다." , e); |
095 | } |
096 | } |
097 |
098 | class SMTPAuthenticator extends Authenticator { |
099 | |
100 | PasswordAuthentication passwordAuthentication; |
101 | |
102 | SMTPAuthenticator(String userName, String password) { |
103 | passwordAuthentication = new PasswordAuthentication(userName, password); |
104 | } |
105 | public PasswordAuthentication getPasswordAuthentication() { |
106 | return passwordAuthentication; |
107 | } |
108 | } |
109 |
110 | } |
- 자바메일을 이용해서 메일 전송을 구현하였다. 사용자 인증을 위해서 Authenticator을 상속받은 SMTPAuthenticator 클래스를 내부에 만들었다. 그리고 starttls을 사용하기 위해 변수를 선언하였다. (starttls게 뭔지 본인은 모른다. 궁금하신분은 RFC-2487)를 참고 바란다.
3. PostMan 실행해보기
- 지난 시간에 만든 PostMan 클래스를 수정해주자. 로그로만 메일 내용을 출력해주던 SimpleMailSendManager 클래스를 지금 만든 SMTPMailSendManager 클래스로 바꾸자.
01 | package kr.kangwoo.postman.core; |
02 |
03 | public class PostMan { |
04 | // ... 생 략 ... |
05 | public static void main(String[] args) { |
06 | PostMan man = new PostMan(); |
07 | MailDao mailDao = new SimpleMailDao(); |
08 | MailTemplateDao mailTemplateDao = new SimpleMailTemplateDao(); |
09 | SimpleMailManager mailManager = new SimpleMailManager(); |
10 | mailManager.setMailDao(mailDao); |
11 | FreemarkerMailTemplateManager mailTemplateManager = new FreemarkerMailTemplateManager(); |
12 | mailTemplateManager.setMailTemplateDao(mailTemplateDao); |
13 | |
14 | SMTPMailSendManager mailSendManager = new SMTPMailSendManager(); |
15 | mailSendManager.setHost( "smtp.gmail.com" ); |
16 | mailSendManager.setPort( 587 ); |
17 | mailSendManager.setStarttlsEnable( true ); |
18 | mailSendManager.setUserName( "계정명" ); |
19 | mailSendManager.setPassword( "계정비밀번호 " ); |
20 | |
21 | man.setMailManager(mailManager); |
22 | man.setMailTemplateManager(mailTemplateManager); |
23 | man.setMailSendManager(mailSendManager); |
24 | |
25 | man.run(); |
26 | } |
27 |
28 | } |
- 여기서는 gmail 계정을 사용하였다.(gmail 계정을 사용할려면 starttls를 사용함으로 해야한다.) 발송할 대상을 바꾸고(꼭 바꿔주시길 바란다.!!! 지난 예제로 실행하면 본인한테 메일이 온다.) 실행해보자.
- 어제 소스를 그대로 사용하시는분은, 무한 루프를 도는 관계로 꼭 강제적으로 중지시켜주기 바란다. 안그러면 미워할거다.
- gmail, naver, daum은 잘 도착한다. ^^;
http://cloudstick.tistory.com/entry/JavaMail-API-SMTP
JavaMail API를 이용하여 SMTP를 구현해 보도록 한다.
JavaMail은 이미 널리 사용되고 있는 이메일의 개념을 모두 클래스화하여 제공한다.
SMTP를 구현하기 위해서는
1. Session
2. Transport
3. Message
4. 프로퍼티 설정
5. SSL/TLS, Plain, Starttls
위 다섯 가지 정도를 알아야한다.
우선 Plain 즉 평문에 대해서 어떤 암호화도 하지 않은 상태로 메일을 보낼때에 대해서는 고려하지 않겠다. 보안 체널을 이용한 메일 전송은 SSL/TLS를 이용한 암시적 보안과 Starttls를 이용한 명시적 보안이 있다.(SSL/TLS 참조)
Starttls를 이용한 메일 전송은 아래와 같다.
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 | public final class SmtpTlsstartImplementation { public void send(String host, String port, String username, String password) { props = System.getProperties(); props.put( "mail.smtp.host" , host); props.put( "mail.smtp.port" , port); props.put( "mail.smtp.auth" , "true" ); props.put( "mail.smtp.starttls.enable" , "true" ); props.put( "mail.smtp.ssl.trust" , host); session = Session.getDefaultInstance(props, new javax.mail.Authenticator() { protected PasswordAuthentication getPasswordAuthentication() { return new PasswordAuthentication(username, password); } }); session.setDebug( true ); //for debug Message mimeMessage = new MimeMessage(session); mimeMessage.setFrom( new InternetAddress( "from@cloudstick.co.kr" )); mimeMessage.setRecipient(Message.RecipientType.TO, new InternetAddress( "to@cloudstick.co.kr" )); mimeMessage.setSubject( "Mail subject" ); mimeMessage.setText( "Mail content by text" ); Transport.send(mimeMessage); } } |
위의 내용 중에서 mail.smtp.starttls.enable이 Starttls를 이용한 메일 보내기의 핵심이다. Starttls는 JavaMail에 TLS모드를 시작하라고 명시적으로 요청한다. 즉 Starttls을 확인하기 전까지 JavaMail API는 해당 메일을 암호화되지 않은 평문으로 보낸다고 가정한다. Starttls 설정을 확인하면 보안 관련 채널을 생성하여 인증서 확인 등의 작업을 거친다. 위의 props 설정 중 props.put("mail.smtp.ssl.trust", host); 를 제거하면 인증서 관련 오류가 발생한다. 이를 해결하기 위해서는 인증서 정보를 로컬에 저장해야 하는데 이메일에서 이러한 작업까지는 필요없을 듯 하다.
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 | public final class SmtpSslImplementation { public void send(String host, String port, String username, String password) { props = System.getProperties(); props.put( "mail.smtp.host" , host); props.put( "mail.smtp.port" , port); props.put( "mail.smtp.auth" , "true" ); props.put( "mail.smtp.ssl.enable" , "true" ); props.put( "mail.smtp.ssl.trust" , host); session = Session.getDefaultInstance(props, new javax.mail.Authenticator() { protected PasswordAuthentication getPasswordAuthentication() { return new PasswordAuthentication(username, password); } }); session.setDebug( true ); //for debug Message mimeMessage = new MimeMessage(session); mimeMessage.setFrom( new InternetAddress( "from@cloudstick.co.kr" )); mimeMessage.setRecipient(Message.RecipientType.TO, new InternetAddress( "to@cloudstick.co.kr" )); mimeMessage.setSubject( "Mail subject" ); mimeMessage.setText( "Mail content by text" ); Transport.send(mimeMessage); } } |
Gmail, Authentication in JavaMail
JavaMail_Intro_송수신_html_첨부.ppt
JavaMail_Intro_송수신_html_첨부.ppt
JavaMail 1.4.3:http://java.sun.com/products/javamail/downloads/index.html
JavaMail 1.4.4 http://www.oracle.com/technetwork/java/index-138643.html
javamail1_4_4.zip
JAF 1.1.1: http://java.sun.com/products/javabeans/jaf/downloads/index.html
JAF는 Java SE 6이상의 버전을 사용할 경우 이미 포함되어 있으므로 다운로드할 필요가 없다.
웹프로젝트에서 Tomcat과 JavaMail API를 사용하는 경우에 간혹 Tomcat에서 javax.mail.Authenticator 클래스를 찾지 못하는 현상이 있을 수 있는데, 이때는 mail.jar, activation.jar 를 Tomcat/common/lib/ 안에 복사해 주면 된다.
Gmail.java
import javax.mail.*;
import javax.mail.internet.*;
import javax.activation.*;
import java.io.*;
import java.util.*;
import java.security.Security;
public class Gmail
{
public static void main(String[] args)
{
Properties p = new Properties();
p.put("mail.smtp.user", "gmail_id@gmail.com"); // Google계정@gmail.com으로 설정
p.put("mail.smtp.host", "smtp.gmail.com");
p.put("mail.smtp.port", "465");
p.put("mail.smtp.starttls.enable","true");
p.put( "mail.smtp.auth", "true");
p.put("mail.smtp.debug", "true");
p.put("mail.smtp.socketFactory.port", "465");
p.put("mail.smtp.socketFactory.class", "javax.net.ssl.SSLSocketFactory");
p.put("mail.smtp.socketFactory.fallback", "false");
//Security.addProvider(new com.sun.net.ssl.internal.ssl.Provider());
try {
Authenticator auth = new SMTPAuthenticator();
Session session = Session.getInstance(p, auth);
session.setDebug(true); // 메일을 전송할 때 상세한 상황을 콘솔에 출력한다.
//session = Session.getDefaultInstance(p);
MimeMessage msg = new MimeMessage(session);
String message = "Gmail SMTP 서버를 이용한 JavaMail 테스트";
msg.setSubject("Gmail SMTP 서버를 이용한 JavaMail 테스트");
Address fromAddr = new InternetAddress("gmail_id@gmail.com"); // 보내는 사람의 메일주소
msg.setFrom(fromAddr);
Address toAddr = new InternetAddress("paran_id@paran.com"); // 받는 사람의 메일주소
msg.addRecipient(Message.RecipientType.TO, toAddr);
msg.setContent(message, "text/plain;charset=KSC5601");
System.out.println("Message: " + msg.getContent());
Transport.send(msg);
System.out.println("Gmail SMTP서버를 이용한 메일보내기 성공");
}
catch (Exception mex) { // Prints all nested (chained) exceptions as well
System.out.println("I am here??? ");
mex.printStackTrace();
}
}
private static class SMTPAuthenticator extends javax.mail.Authenticator {
public PasswordAuthentication getPasswordAuthentication() {
return new PasswordAuthentication("cwiskykim", "cw******"); // Google id, pwd, 주의) @gmail.com 은 제외하세요
}
}
}
GoogleTest.java(다수에게 메일을 전송하는 경우)
import java.security.Security;
import java.util.Properties;
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;
public class GoogleTest {
private static final String SMTP_HOST_NAME = "smtp.gmail.com";
private static final String SMTP_PORT = "465";
private static final String emailMsgTxt = "Gmail SMTP 서버를 사용한 JavaMail 테스트";
private static final String emailSubjectTxt = "Gmail SMTP 테스트";
private static final String emailFromAddress = "cwisky@yahoo.com";
private static final String SSL_FACTORY = "javax.net.ssl.SSLSocketFactory";
private static final String[] sendTo = { "cwisky@navy.com"}; // 수신자가 다수일 경우를 가정해서 배열을 사용함
public static void main(String args[]) throws Exception {
Security.addProvider(new com.sun.net.ssl.internal.ssl.Provider());
new GoogleTest().sendSSLMessage(sendTo, emailSubjectTxt, emailMsgTxt, emailFromAddress);
System.out.println("Sucessfully Sent mail to All Users");
}
public void sendSSLMessage(String recipients[], String subject,
String message, String from) throws MessagingException {
boolean debug = true;
Properties props = new Properties();
props.put("mail.smtp.host", SMTP_HOST_NAME);
props.put("mail.smtp.auth", "true");
props.put("mail.debug", "true");
props.put("mail.smtp.port", SMTP_PORT);
props.put("mail.smtp.socketFactory.port", SMTP_PORT);
props.put("mail.smtp.socketFactory.class", SSL_FACTORY);
props.put("mail.smtp.socketFactory.fallback", "false");
Session session = Session.getDefaultInstance(props,
new javax.mail.Authenticator() {
protected PasswordAuthentication getPasswordAuthentication() {
return new PasswordAuthentication("cwiskykim", "cw******");
}
}
);
session.setDebug(debug);
Message msg = new MimeMessage(session);
InternetAddress addressFrom = new InternetAddress(from);
msg.setFrom(addressFrom);
InternetAddress[] addressTo = new InternetAddress[recipients.length];
for (int i = 0; i < recipients.length; i++) {
addressTo[i] = new InternetAddress(recipients[i]);
}
msg.setRecipients(Message.RecipientType.TO, addressTo);
// Setting the Subject and Content Type
msg.setSubject(subject);
msg.setContent(message, "text/plain;charset=KSC5601");
Transport.send(msg);
}
}
GMail SMTP 서버를 이용하여 텍스트와 첨부파일을 전송하는 예제 프로그램
package mail;
import java.io.File;
import java.security.Security;
import java.util.Properties;
import javax.activation.DataHandler;
import javax.activation.FileDataSource;
import javax.mail.BodyPart;
import javax.mail.Message;
import javax.mail.MessagingException;
import javax.mail.Multipart;
import javax.mail.PasswordAuthentication;
import javax.mail.Session;
import javax.mail.Transport;
import javax.mail.internet.InternetAddress;
import javax.mail.internet.MimeBodyPart;
import javax.mail.internet.MimeMessage;
import javax.mail.internet.MimeMultipart;
public class GmailSMTP {
private static final String SMTP_HOST_NAME = "smtp.gmail.com";
private static final String SMTP_PORT = "465";
private static final String emailMsgTxt = "Gmail SMTP 서버를 사용한 JavaMail 테스트";
private static final String emailSubjectTxt = "Gmail SMTP 테스트";
private static final String emailFromAddress = "google_id@gmail.com";
private static final String SSL_FACTORY = "javax.net.ssl.SSLSocketFactory";
private static final String[] sendTo = { "paran_id@paran.com"};
public static void main(String args[]) throws Exception {
Security.addProvider(new com.sun.net.ssl.internal.ssl.Provider());
new GmailSMTP().sendSSLMessage(sendTo, emailSubjectTxt, emailMsgTxt, emailFromAddress);
System.out.println("Sucessfully Sent mail to All Users");
}
public void sendSSLMessage(String recipients[], String subject,
String message, String from) throws MessagingException {
boolean debug = true;
Properties props = new Properties();
props.put("mail.smtp.host", SMTP_HOST_NAME);
props.put("mail.smtp.auth", "true");
props.put("mail.debug", "true");
props.put("mail.smtp.port", SMTP_PORT);
props.put("mail.smtp.socketFactory.port", SMTP_PORT);
props.put("mail.smtp.socketFactory.class", SSL_FACTORY);
props.put("mail.smtp.socketFactory.fallback", "false");
Session session = Session.getDefaultInstance(props,
new javax.mail.Authenticator() {
protected PasswordAuthentication getPasswordAuthentication() {
return new PasswordAuthentication("cwisk***", "cw*****");
}
}
);
session.setDebug(debug);
Message msg = new MimeMessage(session);
InternetAddress addressFrom = new InternetAddress(from);
msg.setFrom(addressFrom);
InternetAddress[] addressTo = new InternetAddress[recipients.length];
for (int i = 0; i < recipients.length; i++) {
addressTo[i] = new InternetAddress(recipients[i]);
}
msg.setRecipients(Message.RecipientType.TO, addressTo);
// Setting the Subject and Content Type
msg.setSubject(subject);
/*텍스트만 전송하는 경우 아래의 2라인만 추가하면 된다.
* 그러나 텍스트와 첨부파일을 함께 전송하는 경우에는 아래의 2라인을 제거하고
* 대신에 그 아래의 모든 문장을 추가해야 한다.
**/
//msg.setContent(message, "text/plain;charset=KSC5601");
//Transport.send(msg);
/* 텍스트와 첨부파일을 함께 전송하는 경우에는 위의 2라인을 제거하고 아래의 모든 라인을 추가한다.*/
// Create the message part
BodyPart messageBodyPart = new MimeBodyPart();
// Fill the message
messageBodyPart.setText("테스트용 메일의 내용입니다.");
Multipart multipart = new MimeMultipart();
multipart.addBodyPart(messageBodyPart);
// Part two is attachment
messageBodyPart = new MimeBodyPart();
File file = new File("C:/append.txt");
FileDataSource fds = new FileDataSource(file);
messageBodyPart.setDataHandler(new DataHandler(fds));
String fileName = fds.getName(); // 한글파일명은 영문으로 인코딩해야 첨부가 된다.
fileName = new String(fileName.getBytes("KSC5601"), "8859_1");
messageBodyPart.setFileName(fileName);
multipart.addBodyPart(messageBodyPart);
// Put parts in message
msg.setContent(multipart);
// Send the message
Transport.send(msg);
System.out.println("E-mail successfully sent!!");
}
}
위의 내용으로 오류가 발생한다면 아래처럼......
package mail;
import javax.mail.*;
import javax.mail.internet.*;
import javax.activation.*;
import java.io.*;
import java.util.*;
import java.security.Security;
public class GMail
{
public static void main(String[] args)
{
Properties p = new Properties();
p.put("mail.smtp.user", "myid@gmail.com"); // Google계정 아이디@gmail.com으로 설정
p.put("mail.smtp.host", "smtp.gmail.com");
p.put("mail.smtp.port", "465");
p.put("mail.smtp.starttls.enable","true");
p.put( "mail.smtp.auth", "true");
p.put("mail.smtp.debug", "true");
p.put("mail.smtp.socketFactory.port", "465");
p.put("mail.smtp.socketFactory.class", "javax.net.ssl.SSLSocketFactory");
p.put("mail.smtp.socketFactory.fallback", "false");
//Security.addProvider(new com.sun.net.ssl.internal.ssl.Provider());
try {
Authenticator auth = new SMTPAuthenticator();
Session session = Session.getInstance(p, auth);
session.setDebug(true); // 메일을 전송할 때 상세한 상황을 콘솔에 출력한다.
//session = Session.getDefaultInstance(p);
MimeMessage msg = new MimeMessage(session);
String message = "Gmail SMTP 서버를 이용한 JavaMail 테스트";
msg.setSubject("Gmail SMTP 서버를 이용한 JavaMail 테스트");
Address fromAddr = new InternetAddress("google아이디@gmail.com"); // 보내는 사람의 메일주소
msg.setFrom(fromAddr);
Address toAddr = new InternetAddress("수신자아이디@paran.com"); // 받는 사람의 메일주소
msg.addRecipient(Message.RecipientType.TO, toAddr);
/*
msg.setContent(message, "text/plain;charset=KSC5601");
System.out.println("Message: " + msg.getContent());
Transport.send(msg);
*/
BodyPart messageBodyPart = new MimeBodyPart();
// Fill the message
messageBodyPart.setText("Java Mail API를 이용하여 첨부파일을 테스트합니다.");
Multipart multipart = new MimeMultipart();
multipart.addBodyPart(messageBodyPart);
// Part two is attachment
messageBodyPart = new MimeBodyPart();
File file = new File("C:/log.txt");
FileDataSource fds = new FileDataSource(file);
messageBodyPart.setDataHandler(new DataHandler(fds));
messageBodyPart.setFileName(fds.getName());
multipart.addBodyPart(messageBodyPart);
// Put parts in message
msg.setContent(multipart, "text/plain;charset=KSC5601");
// Send the message
Transport.send(msg);
System.out.println("Gmail SMTP서버를 이용한 메일보내기 성공");
}
catch (Exception mex) { // Prints all nested (chained) exceptions as well
System.out.println("I am here??? ");
mex.printStackTrace();
}
}
private static class SMTPAuthenticator extends javax.mail.Authenticator {
public PasswordAuthentication getPasswordAuthentication() {
return new PasswordAuthentication("구글아이디", "구글암호"); // Google id, pwd
}
}
}
Gmail_POP3.java (Gmail계정에 POP3프로토콜을 사용하여 접속하고 자신의 계정에 저장되어 있는 메일을 가져오는 예)
static final String USERNAME = "cwiskykim@gmail.com";
static final String PASSWORD = "00000000";
public GMailPOP3() {}
public static void main(String[] args) {
try {
GMailUtilities gmail = new GMailUtilities();
gmail.setUserPass(USERNAME, PASSWORD); // Gmail 계정 메일주소, 암호
gmail.connect();
gmail.openFolder("INBOX");
int totalMessages = gmail.getMessageCount();
int newMessages = gmail.getNewMessageCount();
System.out.println("Total messages = " + totalMessages);
System.out.println("New messages = " + newMessages);
System.out.println("-------------------------------");
//Uncomment the below line to print the body of the message.
//Remember it will eat-up your bandwidth if you have 100's of messages.
//gmail.printAllMessageEnvelopes();
//gmail.printAllMessages();
POP3DTO[] dtos = gmail.getAllMessages();
for(int i=0;i<dtos.length;i++){
pr(dtos[i].getFrom().toString());
pr(dtos[i].getSubject());
pr(dtos[i].getSentDate().toString());
}
} catch(Exception e) {
e.printStackTrace();
System.exit(-1);
}
}
private static void pr(String str){
System.out.println(str);
}
}
GmailUtilities.java
package mail;
import com.sun.mail.pop3.POP3SSLStore;
import com.sun.mail.util.BASE64DecoderStream;
import java.io.*;
import java.util.*;
import javax.mail.*;
import javax.mail.internet.*;
/* 메일헤더에 포함되는 [FROM, TO, 첨부파일명]은 RFC2047으로 인코딩되어
* 전달되므로 이들 항목이 한글일 경우에는 다시 디코딩하는 것에 주의하세요.
* 예) MimeUtility.decodeText(encodeText)
*/
public class GMailUtilities {
private Session session = null;
private Store store = null;
private String username, password;
private Folder folder;
public GMailUtilities() { }
public void setUserPass(String username, String password) {
this.username = username;
this.password = password;
}
public void connect() throws Exception {
String SSL_FACTORY = "javax.net.ssl.SSLSocketFactory";
Properties pop3Props = new Properties();
pop3Props.setProperty("mail.pop3.socketFactory.class", SSL_FACTORY);
pop3Props.setProperty("mail.pop3.socketFactory.fallback", "false");
pop3Props.setProperty("mail.pop3.port", "995");
pop3Props.setProperty("mail.pop3.socketFactory.port", "995");
URLName url = new URLName("pop3", "pop.gmail.com", 995, "",
username, password);
session = Session.getInstance(pop3Props, null);
store = new POP3SSLStore(session, url);
store.connect();
}
public void openFolder(String folderName) throws Exception {
// Open the Folder
folder = store.getDefaultFolder();
folder = folder.getFolder(folderName); // INBOX
if (folder == null) {
throw new Exception("Invalid folder");
}
// try to open read/write and if that fails try read-only
try {
folder.open(Folder.READ_WRITE);
} catch (MessagingException ex) {
folder.open(Folder.READ_ONLY);
}
}
public void closeFolder() throws Exception {
folder.close(false);
}
public int getMessageCount() throws Exception {
return folder.getMessageCount();
}
public int getNewMessageCount() throws Exception {
return folder.getNewMessageCount();
}
public void disconnect() throws Exception {
store.close();
}
public void printMessage(int messageNo) throws Exception {
System.out.println("Getting message number: " + messageNo);
Message m = null;
try {
m = folder.getMessage(messageNo);
dumpEnvelope(m);
} catch (IndexOutOfBoundsException iex) {
System.out.println("Message number out of range");
}
}
public void printAllMessageEnvelopes() throws Exception {
// Attributes & Flags for all messages ..
Message[] msgs = folder.getMessages();
// Use a suitable FetchProfile
FetchProfile fp = new FetchProfile();
fp.add(FetchProfile.Item.ENVELOPE);
folder.fetch(msgs, fp);
for (int i = 0; i < msgs.length; i++) {
System.out.println("--------------------------");
System.out.println("MESSAGE #" + (i + 1) + ":");
dumpEnvelope(msgs[i]);
}
}
public void printAllMessages() throws Exception {
// Attributes & Flags for all messages ..
Message[] msgs = folder.getMessages();
// Use a suitable FetchProfile
FetchProfile fp = new FetchProfile();
fp.add(FetchProfile.Item.ENVELOPE);
folder.fetch(msgs, fp);
for (int i = 0; i < msgs.length; i++) {
System.out.println("--------------------------");
System.out.println("MESSAGE #" + (i + 1) + ":");
dumpEnvelope(msgs[i]);
}
}
public POP3DTO[] getAllMessages() throws Exception {
POP3DTO[] dtos = null;
// Attributes & Flags for all messages ..
Message[] msgs = folder.getMessages();
dtos = new POP3DTO[msgs.length];
// Use a suitable FetchProfile
FetchProfile fp = new FetchProfile();
fp.add(FetchProfile.Item.ENVELOPE);
folder.fetch(msgs, fp);
for (int i = 0; i < msgs.length; i++) {
dtos[i] = new POP3DTO();
dtos[i].setFrom(MimeUtility.decodeText(msgs[i].getFrom()[0].toString()));
dtos[i].setSubject(msgs[i].getSubject());
dtos[i].setSentDate(msgs[i].getSentDate());
}
return dtos;
}
public static void dumpEnvelope(Message m) throws Exception {
pr(" ");
Address[] a;
// FROM
if ((a = m.getFrom()) != null) {
for (int j = 0; j < a.length; j++)
pr("FROM: " + MimeUtility.decodeText(a[j].toString()));
}
// TO
if ((a = m.getRecipients(Message.RecipientType.TO)) != null) {
for (int j = 0; j < a.length; j++) {
pr("TO: " + MimeUtility.decodeText(a[j].toString()));
}
}
// SUBJECT
pr("SUBJECT: " + m.getSubject());
// DATE
Date d = m.getSentDate();
pr("SendDate: " +
(d != null ? d.toString() : "UNKNOWN"));
// CONTENT TYPE
String contentType = m.getContentType();
pr("CONTENT TYPE: " +contentType);
// CONTENT
/* 단순한 구조의 메일은 MimeMessage 안에 바로 텍스트(text/plain, text/html)가 포함되는 구조로 되어있지만,
* 대부분의 메일 내용은 JavaMail 개발자 입장에서 보았을 때 메일본문이 바로 발견되는 것이 아니라
* MimeMessage 내부의 Multipart 안에 몇개의 BodyPart로 구성되어 있고 각 BodyPart 안에는 첨부파일
* 이 있으며, 어떤 BodyPart 안에는 또 다시 Multipart가 포함되고 그 안에 일반텍스(text/plain)나
* HTML(text/html)형식의 메일 본문이 포함되어 있는 경우도 많다.
*/
pr("Message.getContent()-------------------");
pr("CONTENT: "+ m.getContent());
// 첨부파일
if( m.isMimeType("multipart/*") ) {
System.out.println("첨부파일이 포함된 메일");
handleMultipart(m);
//pr(str);
}
}
/* 첨부파일을 다루는 메소드, 첨부파일을 로컬시스템에 다운로드한다
* 첨부파일은 Base64 인코딩된 경우와 그렇지 않은 경우로 구분하여 스트림을 사용한다
* MimeMultipart 안에는 다수개의 MimeBodypart(파트)가 포함될 수 있고 각 파트 안에는
* 텍스트(text/plain, text/html), 첨부파일, 또 다른 MimeMultipart 등이 로 존재한다.
* 한개의 파트 안에 또 다른 멀티파트가 포함되어 있을 경우에는 그 멀티파트에 포함되어 있는
* 것은 텍스트나 HTML 이었다.
*/
public static String handleMultipart(Message msg) {
String content = null;
try {
String disposition;
BodyPart part;
Multipart mp = (Multipart) msg.getContent(); // 멀티파트 구함
int mpCount = mp.getCount();
pr("멀티파트 안의 아이템 수:"+mpCount);
for (int m = 0; m < mpCount; m++) {
part = mp.getBodyPart(m); // 멀티파트내의 한개 파트 구함
String partContentType = part.getContentType();
disposition = part.getDisposition(); // 파트의 성격
Object partContent = part.getContent(); // 한개 파트의 내용을 구함
pr(m+1+"번 파트-----disposition:"+disposition);
/*멀티파트 내의 한개 파트가 메일 본문인 경우 */
if(partContentType.startsWith("text/")&& disposition==null){
String txtContent = part.getContent().toString();
pr("멀티파트 안의 본문:"+txtContent);
}/*멀티파트 내의 한개 파트가 첨부파일이고 파일명이 한글인 경우 */
else if(partContent instanceof BASE64DecoderStream)
{
BASE64DecoderStream ds = (BASE64DecoderStream)partContent;
String filename = part.getFileName();
// RFC 2047으로 인코딩된 문자열을 다시 디코딩한다.
filename = MimeUtility.decodeText(filename);
pr("한글 파일명:"+filename);
byte[] buf = new byte[ds.available()];
ds.read(buf);
ds.close();
// 첨부파일을 로컬시스템에 다운로드한다
saveLocal(filename, buf);
}
else if (disposition != null &&
(disposition.equals(Part.INLINE)
||disposition.equals(Part.ATTACHMENT)))/*첨부파일명이 영문인 경우*/
{
String filename = part.getFileName();
filename = MimeUtility.decodeText(filename);
pr("영문 파일명:"+filename);
InputStream is = part.getInputStream();
byte[] buf = new byte[is.available()];
is.read(buf);
is.close();
saveLocal(filename, buf);
} else {/*한개의 파트 안에 다시 멀티 파트가 포함된 경우, 대부분 텍스트나 HTML */
if(partContent instanceof MimeMultipart){
MimeMultipart multipart = (MimeMultipart)partContent;
int cnt = multipart.getCount();
for(int i=0;i<cnt;i++){
BodyPart bp = multipart.getBodyPart(i);
pr("파트 안의 멀티파트 정보:"+bp.getContentType());
pr("파트 안의 멀티파트 내용:"+bp.getContent());
}
}
}
}// end of for()
} catch (Exception ex) {
ex.printStackTrace();
}
return content;
}
static String indentStr = " ";
static int level = 0;
/**
* Print a, possibly indented, string.
*/
public static void pr(String s) {
System.out.print(indentStr.substring(0, level * 2));
System.out.println(s);
}
private static void saveLocal(String filename, byte[]buf){
FileOutputStream fout = null;
try{
fout = new FileOutputStream("C:/append/"+filename);
fout.write(buf);
fout.close();
}catch(Exception fne){
fne.printStackTrace();
}
}
}
'차근차근 > JAVA JSP' 카테고리의 다른 글
이미지 클릭 시 확대 , 팝업창 X (0) | 2014.10.20 |
---|---|
자바소스코드 배경 이미지 넣기 - 자료모음 (0) | 2014.10.20 |
putExtra int값 넘기고 받기 (0) | 2014.10.08 |
java.lang.ArrayIndexOutOfBoundsException (0) | 2014.09.26 |
jsp 이미지 슬라이드 (0) | 2014.09.24 |
'차근차근/JAVA JSP'의 다른글
- 현재글javamail