본문 바로가기
Back-end/JAVA

[SMTP] JAVA로 메일 발송 하기. (With. 첨부파일 )

by 허도치 2020. 2. 20.
0. 서론

 JAVA에서 Gmail을 이용하여 메일을 발송하는 예제를 만들어보려고 한다. 굳이 프로젝트를 생성하지 않고 JAVA파일과 jar파일 2개만 있으면 쉽게 만들 수 있다. 그래도, 프로젝트를 만들고 싶다면 Maven 프로젝트로 생성하길 바란다.

 

 

 

1. 프로젝트 준비
1-1. Gmail 인증을 위한 앱 비밀번호 발급

[ 구글 계정 ] > [ 보안 ] > [ Google에 로그인 ]

1) 구글 계정으로 접속 후 로그인.
   : https://myaccount.google.com/

2) [ 보안 ] > [ Google에 로그인 ] > [ 2단계 인증 ]을 클릭 후 등록.
   : https://myaccount.google.com/signinoptions/two-step-verification

3) [ 보안 ] > [ Google에 로그인 ] > [ 앱 비밀번호 ]을 클릭.
   : https://myaccount.google.com/apppasswords

4) 앱 비밀번호를 생성할 앱 및 기기를 선택.
   : [ 앱 선택 ]은 '메일'을 선택.
   : [ 기기 선택 ]은 아무거나 선택.

5) 생성 클릭
   : 발급된 패스워드가 팝업에 패스워드가 발급되며
   : 발급 받은 패스워드는 따로 저장.

 

1-2. JAR파일 다운로드

1) 메일을 발송하기 위해 필요한 2개의 JAR파일을 다운로드.
   : activation-1.1.jar [ 다운로드 ]
   : mail-1.4.7.jar [ 다운로드 ]

2) Maven을 사용한다면 pom.xml에 두개의 dependency 추가.
   <dependency>
       <groupId>javax.activation</groupId>
       <artifactId>activation</artifactId>
       <version>1.1</version>
   </dependency>

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

 

 

 

2. 텍스트(HTML) 메일 발송
2-1. 스크립트 작성
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
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
// App.java
 
import java.util.Date;
import java.util.Properties;
 
import javax.activation.CommandMap;
import javax.activation.MailcapCommandMap;
import javax.mail.Authenticator;
import javax.mail.Message;
import javax.mail.Message.RecipientType;
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;
import javax.mail.internet.MimeUtility;
 
public class App {
  public static void main(String args[]) {
    sendMail();
  }
  
  /**
   * SendMail
   */
  public static void sendMail() {
    // 메일 인코딩
    final String bodyEncoding = "UTF-8"//콘텐츠 인코딩
    
    String subject = "메일 발송 테스트";
    String fromEmail = "보낼 이메일 주소";
    String fromUsername = "SYSTEM MANAGER";
    String toEmail = "받을 이메일 주소1,받을 이메일 주소2,"// 콤마(,)로 여러개 나열
    
    final String username = "구글 계정";         
    final String password = "발급받은 앱 비밀번호";
    
    // 메일에 출력할 텍스트
    StringBuffer sb = new StringBuffer();
    sb.append("<h3>안녕하세요</h3>\n");
    sb.append("<h4>개발하는 도치입니다.</h4>\n");    
    String html = sb.toString();
    
    // 메일 옵션 설정
    Properties props = new Properties();    
    props.put("mail.transport.protocol""smtp");
    props.put("mail.smtp.host""smtp.gmail.com");
    props.put("mail.smtp.port""465");
    props.put("mail.smtp.auth""true");
 
    props.put("mail.smtp.quitwait""false");
    props.put("mail.smtp.socketFactory.port""465");
    props.put("mail.smtp.socketFactory.class""javax.net.ssl.SSLSocketFactory");
    props.put("mail.smtp.socketFactory.fallback""false");
    
    try {
      // 메일 서버  인증 계정 설정
      Authenticator auth = new Authenticator() {
        protected PasswordAuthentication getPasswordAuthentication() {
          return new PasswordAuthentication(username, password);
        }
      };
      
      // 메일 세션 생성
      Session session = Session.getInstance(props, auth);
      
      // 메일 송/수신 옵션 설정
      Message message = new MimeMessage(session);
      message.setFrom(new InternetAddress(fromEmail, fromUsername));
      message.setRecipients(RecipientType.TO, InternetAddress.parse(toEmail, false));
      message.setSubject(subject);
      message.setSentDate(new Date());
      
      // 메일 콘텐츠 설정
      Multipart mParts = new MimeMultipart();
      MimeBodyPart mTextPart = new MimeBodyPart();
      MimeBodyPart mFilePart = null;
 
      // 메일 콘텐츠 - 내용
      mTextPart.setText(html, bodyEncoding, "html");
      mParts.addBodyPart(mTextPart);
            
      // 메일 콘텐츠 설정
      message.setContent(mParts);
      
      // MIME 타입 설정
      MailcapCommandMap MailcapCmdMap = (MailcapCommandMap) CommandMap.getDefaultCommandMap();
      MailcapCmdMap.addMailcap("text/html;; x-java-content-handler=com.sun.mail.handlers.text_html");
      MailcapCmdMap.addMailcap("text/xml;; x-java-content-handler=com.sun.mail.handlers.text_xml");
      MailcapCmdMap.addMailcap("text/plain;; x-java-content-handler=com.sun.mail.handlers.text_plain");
      MailcapCmdMap.addMailcap("multipart/*;; x-java-content-handler=com.sun.mail.handlers.multipart_mixed");
      MailcapCmdMap.addMailcap("message/rfc822;; x-java-content-handler=com.sun.mail.handlers.message_rfc822");
      CommandMap.setDefaultCommandMap(MailcapCmdMap);
 
      // 메일 발송
      Transport.send( message );
      
    } catch ( Exception e ) {
      e.printStackTrace();
    }
  }
}
cs

 

2-2. 실행

1) CLASSPATH 환경변수 설정
   $ SET CLASSPATH=%CLASSPATH%;C:\libs\activation-1.1.jar;C:\libs\mail-1.4.7.jar;

2) JAVA 컴파일 ( Class파일 생성 )
   $ javac App.java

3) JAVA Class 실행
   $ java App

* Maven 프로젝트인 경우 [ App.java ] 파일을 오른쪽 클릭한 후 [ Run As ] > [ Java Application ]을 클릭하여 실행.

 

2-3. 실행 결과

- 메일이 정상적으로 발송되고 받은 것을 확인할 수 있음.
- 텍스트를 HTML로 작성하면 내용에 이미지나 표 등을 추가할 수 있음.

 

 

 

3. 첨부파일이 포함된 메일 발송
3-1. 스크립트 작성
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
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
// App.java
 
import java.util.Date;
import java.util.Properties;
 
import javax.activation.CommandMap;
import javax.activation.MailcapCommandMap;
import javax.mail.Authenticator;
import javax.mail.Message;
import javax.mail.Message.RecipientType;
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;
import javax.mail.internet.MimeUtility;
 
public class App {
  public static void main(String args[]) {
    sendMail();
  }
  
  /**
   * SendMail
   */
  public static void sendMail() {
    // 메일 인코딩
    final String bodyEncoding = "UTF-8"//콘텐츠 인코딩
    
    String subject = "메일 발송 테스트";
    String fromEmail = "보낼 이메일 주소";
    String fromUsername = "SYSTEM MANAGER";
    String toEmail = "받을 이메일 주소1,받을 이메일 주소2,"// 콤마(,)로 여러개 나열
    
    final String username = "구글 계정";         
    final String password = "발급받은 앱 비밀번호";
    
    // 메일에 출력할 텍스트
    StringBuffer sb = new StringBuffer();
    sb.append("<h3>안녕하세요</h3>\n");
    sb.append("<h4>개발하는 도치입니다.</h4>\n");    
    String html = sb.toString();
    
    // 메일 옵션 설정
    Properties props = new Properties();    
    props.put("mail.transport.protocol""smtp");
    props.put("mail.smtp.host""smtp.gmail.com");
    props.put("mail.smtp.port""465");
    props.put("mail.smtp.auth""true");
 
    props.put("mail.smtp.quitwait""false");
    props.put("mail.smtp.socketFactory.port""465");
    props.put("mail.smtp.socketFactory.class""javax.net.ssl.SSLSocketFactory");
    props.put("mail.smtp.socketFactory.fallback""false");
    
    try {
      // 메일 서버  인증 계정 설정
      Authenticator auth = new Authenticator() {
        protected PasswordAuthentication getPasswordAuthentication() {
          return new PasswordAuthentication(username, password);
        }
      };
      
      // 메일 세션 생성
      Session session = Session.getInstance(props, auth);
      
      // 메일 송/수신 옵션 설정
      Message message = new MimeMessage(session);
      message.setFrom(new InternetAddress(fromEmail, fromUsername));
      message.setRecipients(RecipientType.TO, InternetAddress.parse(toEmail, false));
      message.setSubject(subject);
      message.setSentDate(new Date());
      
      // 메일 콘텐츠 설정
      Multipart mParts = new MimeMultipart();
      MimeBodyPart mTextPart = new MimeBodyPart();
      MimeBodyPart mFilePart = null;
 
      // 메일 콘텐츠 - 내용
      mTextPart.setText(html, bodyEncoding, "html");
      mParts.addBodyPart(mTextPart);
            
      // 메일 콘텐츠 설정
      message.setContent(mParts);
      
      // MIME 타입 설정
      MailcapCommandMap MailcapCmdMap = (MailcapCommandMap) CommandMap.getDefaultCommandMap();
      MailcapCmdMap.addMailcap("text/html;; x-java-content-handler=com.sun.mail.handlers.text_html");
      MailcapCmdMap.addMailcap("text/xml;; x-java-content-handler=com.sun.mail.handlers.text_xml");
      MailcapCmdMap.addMailcap("text/plain;; x-java-content-handler=com.sun.mail.handlers.text_plain");
      MailcapCmdMap.addMailcap("multipart/*;; x-java-content-handler=com.sun.mail.handlers.multipart_mixed");
      MailcapCmdMap.addMailcap("message/rfc822;; x-java-content-handler=com.sun.mail.handlers.message_rfc822");
      CommandMap.setDefaultCommandMap(MailcapCmdMap);
 
      // 메일 발송
      Transport.send( message );
      
    } catch ( Exception e ) {
      e.printStackTrace();
    }
  }
}
cs

 

3-2. 실행

1) CLASSPATH 환경변수 설정
   $ SET CLASSPATH=%CLASSPATH%;C:\work\java\libs\activation-1.1.jar;C:\work\java\libs\mail-1.4.7.jar;

2) JAVA 컴파일 ( Class파일 생성 )
   $ javac App.java

3) JAVA Class 실행
   $ java App

* Maven 프로젝트인 경우 [ App.java ] 파일을 오른쪽 클릭한 후 [ Run As ] > [ Java Application ]을 클릭하여 실행.

 

3-3. 실행 결과

- 본문 텍스트와 함께 첨부파일이 함께 전송된 것을 확인할 수 있음.
- 만약, 메일이 정상적으로 발송되었는데 파일이 없다면, 설정한 경로에 파일이 있는지 확인해 볼 것.

 

 

3-4. 오류 발생

- 첨부파일로 보낼 수 없는 확장자인 경우 위와 같은 에러가 발생함.
- 자세한 내용은 공식 문서를 참조.

 

 

 

마치며

- Gmail이 무료로 SMTP를 지원해주기 때문에 간단하게 메일을 보낼 수 있었다. 하지만, 무제한으로 사용할 수 있는 것이 아니기 때문에 메일을 마구 보내는 것은 삼가해야한다.
- 이 메일을 발송하는 기능을 이용하여 프로그램이 종료되었을 때의 결과를 메일로 받을 때 사용할 수 있을 것 같다.
- JAVA를 포스팅할 때마다 느끼는 거지만 소스가 너무 길어서 블로그에 정리하기가 너무 복잡한것 같다.

댓글