Programming language/Java

[Java]Gmail SMTP를 이용한 메일 보내기

  • -
반응형

오늘은 Gmail을 이용한 메일 보내는 기능을 구현해봤습니다.


자바에서 메일을 보내기 위해서는 SMTP 서버가 있어야 합니다.

SMTP는 "Simple Mail Transfer Protocol"의 약자로 전자 메일 전송을 위한 표준 프로토콜입니다.

 

아래 그림과 같이 우리가 보낸 메일은 SMTP 서버로 전송이 되고 SMTP 서버가 해당 메일 주소로 메일을 전송해주는 역할을 합니다. 때문에 자체적인 SMTP 서버가 없다면 외부의 SMTP 서버를 이용하는 방법이 있습니다.

 

아이콘 출처 : flaticon

본 포스팅에서는 Gmail의 SMTP 서버를 이용한 메일 보내기를 해볼 것입니다.

먼저 메일을 보내기 위해서는 mail.jar 라이브러리가 필요합니다.

☞ https://mvnrepository.com/artifact/javax.mail/mail/1.4.7

 

사이트에 접속해서 아래 표시된 jar 파일을 다운받으면 됩니다.

 

다운받은 mail-1.4.7.jar 파일은 프로젝트의 WEB-INF - lib 폴더에 저장합니다.

 

+ Gmail SMTP를 이용하기 위해서는 계정 설정을 해주어야 합니다.

아래 화면에서 Google 계정에 들어가면 로그인 및 보안 설정이 있습니다.

 

 

스크롤을 맨 아래로 내리면 보안 수준이 낮은 앱 허용이 보이는데 사용으로 바꿔주어야 합니다.

 

이제 간단한 셋팅은 끝났습니다.

자바로 메일 보내는 코드는 구글링을 해보면 금방 찾아낼 수 있습니다.

 

본 예제에서는 인증 부분과 보내기 부분을 나누어 구현해봤습니다.

package web.mail;
 
import javax.mail.Authenticator;
import javax.mail.PasswordAuthentication;
 
public class MailAuth extends Authenticator{
    
    PasswordAuthentication pa;
    
    public MailAuth() {
        String mail_id = "gmail 아이디";
        String mail_pw = "패스워드 입력";
        
        pa = new PasswordAuthentication(mail_id, mail_pw);
    }
    
    public PasswordAuthentication getPasswordAuthentication() {
        return pa;
    }
}

 

메일을 보내기 위해 추가한 mail-1.4.7 jar에는 javax.mail 패키지가 들어있습니다.

javax.mail 패키지의 주요 클래스는 Session, Message, Address, Authenticator, Tranport 등이 있습니다. SMTP 서버에 연결해 사용자 인증을 하기 위해서 Authenticator 클래스 사용이 필요합니다.

 

Authenticator를 사용하기 위해서는 PasswordAuthenticator 클래스로부터 인스턴스를 생성하고 getPasswordAuthentication 메소드로 리턴받아야 합니다.

PasswordAuthentication 클래스는 사용자의 아이디와 패스워드를 입력받아 반환하도록 재정의합니다.

package web.mail;
 
import java.io.UnsupportedEncodingException;
import java.util.Date;
import java.util.Properties;
 
import javax.mail.Authenticator;
import javax.mail.Message;
import javax.mail.MessagingException;
import javax.mail.Session;
import javax.mail.Transport;
import javax.mail.internet.AddressException;
import javax.mail.internet.InternetAddress;
import javax.mail.internet.MimeMessage;
 
public class MailSend {
    
    public void MailSend() {
        Properties prop = System.getProperties();
        prop.put("mail.smtp.starttls.enable", "true");
        prop.put("mail.smtp.host", "smtp.gmail.com");
        prop.put("mail.smtp.auth", "true");
        prop.put("mail.smtp.port", "587");
        
        Authenticator auth = new MailAuth();
        
        Session session = Session.getDefaultInstance(prop, auth);
        
        MimeMessage msg = new MimeMessage(session);
    
        try {
            msg.setSentDate(new Date());
            
            msg.setFrom(new InternetAddress("shxorld@gmail.com", "VISITOR"));
            InternetAddress to = new InternetAddress("szhyun2002@gmail.com");         
            msg.setRecipient(Message.RecipientType.TO, to);            
            msg.setSubject("제목", "UTF-8");            
            msg.setText("안녕하세요 테스트 메일입니다.", "UTF-8");            
            
            Transport.send(msg);
            
        } catch(AddressException ae) {            
            System.out.println("AddressException : " + ae.getMessage());           
        } catch(MessagingException me) {            
            System.out.println("MessagingException : " + me.getMessage());
        } catch(UnsupportedEncodingException e) {
            System.out.println("UnsupportedEncodingException : " + e.getMessage());
        }
                
    }
}
 

Properties 클래스는 시스템의 속성을 객체로 생성하는 클래스입니다. Hashtable을 상속받은 클래스로 속성과 값은 1:1로 저장이 됩니다.

 

prop.put("mail.smtp.starttls.enable", "true");
prop.put("mail.smtp.host", "smtp.gmail.com");
prop.put("mail.smtp.auth", "true");
prop.put("mail.smtp.port", "587");

이 부분은 TLS와 SSL의 사용에 따라 설정값이 다른데 위 코드는 TLS의 경우입니다. 

(https://stackoverflow.com/questions/20290625/javamail-javax-mail-authenticationfailedexception 참조)

 

prop.put("mail.smtp.starttls.enable""true"); - 로그인시 TLS를 사용할 것인지 설정

prop.put("mail.smtp.host""smtp.gmail.com"); - 이메일 발송을 처리해줄 SMTP서버

prop.put("mail.smtp.auth""true"); - SMTP 서버의 인증을 사용한다는 의미

rop.put("mail.smtp.port""587"); - TLS의 포트번호는 587(SSL의 포트번호는 465입니다)

 

Authenticator auth = new MailAuth();    
Session session = Session.getDefaultInstance(prop, auth);

MailAuth.java 에서 Authenticator를 상속받아 생성한 MailAuth 클래스를 받아 세션을 생성합니다.

getDefaultInstance의 첫 번째 파라미터는 앞서 설정한 메일 처리 환경입니다.

 

MimeMessage msg = new MimeMessage(session);

MimeMessage는 Message (추상)클래스를 상속받은 인터넷 메일을 위한 클래스입니다. 위에서 생성한 세션을 담아 msg 객체를 생성합니다.

 

msg.setSentDate(new Date());

보내는 날짜를 지정합니다.

 

msg.setFrom(new InternetAddress("shxorld@gmail.com", "VISITOR"));

Message 클래스의 setFrom() 메소드를 사용하여 발송자(발송자의 메일, 발송자명)를 지정합니다. InternetAddress 클래스는 이메일 주소를 나타날 때 사용하는 클래스입니다.

 

InternetAddress to = new InternetAddress("szhyun2002@gmail.com");

수신자의 메일을 생성합니다.

 

msg.setRecipient(Message.RecipientType.TO, to);

Message 클래스의 setRecipient() 메소드를 사용하여 수신자를 설정합니다. setRecipient() 메소드로 수신자, 참조, 숨은 참조 설정이 가능합니다.

  • Message.RecipientType.TO : 받는 사람
  • Message.RecipientType.CC : 참조
  • Message.RecipientType.BCC : 숨은 참조

 

페이지를 하나 만들고 테스트 해보겠습니다.

 

main.jsp

<script type="text/javascript">
function send_mail(){
    window.open("./test_mail.jsp", "", "width=370, height=360, resizable=no, scrollbars=no, status=no");
}
</script>
<div class="form-group" style="width: 38%; margin: 10px auto;">  
  <button type="button" class="btn btn-primary btn-lg btn-block" onclick="send_mail()">보내기</button>
</div>

 

send_mail() 함수는 팝업창으로 test_mail.jsp 페이지를 띄어줍니다.

현재는 메일을 보내는 것만 구현이 되어있고 메일 보내기를 실패했을 때 처리는 되지 않은 상태입니다. 즉 클라이언트단에서 예외처리가 없는 상태. 따라서 실패하면 콘솔창에 에러 내역만 뜨고 팝업창에 COMPLETE 메시지는 무조건 뜨게 되어있습니다. 이 부분은 각자 만들어보는 것도 좋을 것 같네요 :)

 

test_mail.jsp

<%@ page contentType="text/html; charset=UTF-8" %>
<%@ include file="/common/ssi.jsp" %>
<%@ include file="/common/resource.jsp" %>

<%@ page import="web.mail.*"  %>

<%
MailSend ms = new MailSend();
ms.MailSend();

out.println("COMPLETE");
%>

 

메일이 성공적으로 보내지면 요렇게 메일이 도착합니다.

 


+피드백은 언제나 환영입니다 :)

 

반응형

'Programming language > Java' 카테고리의 다른 글

[Java]User-Agent를 이용한 브라우저 체크  (0) 2020.10.29
[Java]날짜 계산하기  (0) 2019.12.31
[Error]java.lang.UnsupportedClassVersionError  (0) 2018.08.24
[Java]try catch finally  (0) 2018.08.17
[Java]Split 함수  (0) 2018.08.13
Contents

포스팅 주소를 복사했습니다

이 글이 도움이 되었다면 공감 부탁드립니다.