본문 바로가기

Web

JavaMailSender란 녀석을 만났다.

728x90
반응형

프로젝트 진행 중 메일 전송 로직을 개발 해야만 했다.

 

문자 서비스, 알림톡 서비스와는 다르게 메일 서비스는 무료로 사용 할 수 있는 거 같다.

(이메일을 보내는데 우리가 비용을 지불하지 않지...)

 

그리고 고맙게도 JAVA에선 이미 메일을 보낼 수 있게 개발 해놓은 인터페이스가 존재하는데

그것이 바로 'JavaMailSender' 이다.

 

****JavaMailSender를 이용해서 메일 전송 로직을 개발하려면 사용하는 메일 사이트에서 선 작업이 필요한데 본 글에선 생략 하겠다.

 

본인은 구글 메일 gmail을 사용하였다.

개발 환경 : spring, gradle

 

자 그럼 코딩을 시작해보자.

 

1. build.gradle에 implementation 시켜줘야한다.

// JavaMailSender
implementation group: 'com.sun.mail', name: 'javax.mail', version: '1.6.2'
implementation group: 'org.springframework.boot', name: 'spring-boot-starter-mail', version: '2.5.1'

// mail template 사용을 위해서
implementation 'org.springframework.boot:spring-boot-starter-thymeleaf'

 

2. application.properties 파일에 메일 설정 정보를 추가하자.

# 이메일 발송 정보 세팅
spring.mail.host=smtp.gmail.com
spring.mail.port=587
spring.mail.properties.mail.smtp.auth=true
spring.mail.properties.mail.smtp.starttls.enable=true
spring.mail.transport.protocol=smtp
spring.mail.debug=true
spring.mail.default.encoding=UTF-8
spring.mail.mime.charset=UTF-8
spring.mail.username=본인 이메일 주소
spring.mail.password=본인 이메일 비밀번호

# 이메일 발송시 사용하는 html 템플릿 설정
## thymeleaf default settings
spring.thymeleaf.prefix=/WEB-INF/views/pages/
spring.thymeleaf.suffix=.html
spring.thymeleaf.mode=HTML
spring.thymeleaf.encoding=UTF-8
spring.thymeleaf.cache=false

여기서 thymeleaf가 들어간 이유는 본인이 진행하는 프로젝트는 현재 jsp 파일을 사용중이다.

하지만 메일을 보낼 때 그냥 텍스트 형식으로 보내는 것이 아니라 디자인이 된 페이지 형태로 메일을 보내려고 한다.

그래서 메일 전송 시에 사용할 페이지를 하나 지정 해주는 작업이다.

이 때 사용되는 페이지는 html파일 thymeleaf로 만들었다.

 

 spring.mail.host 정보와 port 정보는 G메일이 아닌 다른 메일을 사용한다면 그에 맞는 정보를 입력 해줘야 한다.

 

 

3. DTO 생성

@Data
public class RequestMail {

private String title; // 메일제목
private String sendTo; // 수신자
private String templates; // 사용할 templates 파일 이름
private Map context; // 내용

public void setTemplates(String templates) {
     this.templates = "mail/"+templates;
    }
}

여기서 setTemplates만 따로 재정의 한 이유는

사용할 templates 경로가 위 properties파일에서 정의한 /WEB-INF/views/pages/ 뒤에 'mail/' 이라는 경로가 추가 되어야 하기 때문이다.

 

만약 properties 파일에서  /WEB-INF/views/pages/mail 이라고 설정했다면 프로젝트 내에서 사용하는 모든 thymeleaf에 적용 되기 때문에 따로 DTO에서 설정 해주었다.

 

 

4. Service 생성

@Slf4j
@RequiredArgsConstructor
@Service
public class EmailService {

private final JavaMailSender mailSender;

private final SpringTemplateEngine templateEngine;

public void sendMail(RequestMail requestMail) throws MessagingException, IOException {

     MimeMessage message = mailSender.createMimeMessage();
     MimeMessageHelper helper = new MimeMessageHelper(message, true, "UTF-8");

     helper.setSubject(requestMail.getTitle()); //메일 제목 설정
     helper.setTo(requestMail.getSendTo()); // 수신자 설정

     //템플릿에 전달할 데이터 설정
     Context context = new Context();
     context.setVariables(requestMail.getContext()); // 내용 설정

     //메일 내용 설정 : 템플릿 프로세스
     String html = templateEngine.process(requestMail.getTemplates(), context);
     helper.setText(html, true);
  
     mailSender.send(message);
    }

}

 

5. templates(html) 생성

<!DOCTYPE html>
<html lang="ko" xmlns:th="http://www.thymeleaf.org">
<head>
<meta charset="UTF-8">
<meta name="Generator" content="EditPlus®">
<meta name="Author" content="">
<meta name="Keywords" content="">
<meta name="Description" content="">
<title>메일 테스트</title>
</head>
<body>
<table cellpadding="0" cellspacing="0" border="0" style="table-layout:fixed;max-width:800px;min-width:320px;font-family: small/ 1.5 Arial,Helvetica,sans-serif;">
<tbody>
<tr>
<td align="center" bgcolor="#ffffff" style="padding:20px 10px 40px 10px">
<table cellpadding="0" cellspacing="0" border="0" width="100%" align="center" style="table-layout:fixed">
<tbody>
<tr>
<td>
<h1 style="margin:13px 0 12px 0;line-height:0;font-size:0">
</h1>
<table cellpadding="0" cellspacing="0" border="0" width="100%" style="table-layout:fixed">
<tbody>
<tr>
<td bgcolor="#ffffff" style="font-family:AppleSDGothic,apple sd gothic neo,noto sans korean,noto sans korean regular,noto sans cjk kr,noto sans cjk,nanum gothic,malgun gothic,dotum,arial,helvetica,MS Gothic,sans-serif!important">
<h2 style="color:#222; margin:5px 0 0 0;padding-bottom:19px;border-bottom:2px solid #212121;font-size:28px;line-height:1.5">메일 테스트</h2>
</td>
</tr>
</tbody>
</table>
<table cellpadding="0" cellspacing="0" border="0" width="100%" style="table-layout:fixed">
<tbody>
<tr>
<td style="padding:38px 0 0 0;font-size:16px;color:#212121;line-height:1.5;font-family:AppleSDGothic,apple sd gothic neo,noto sans korean,noto sans korean regular,noto sans cjk kr,noto sans cjk,nanum gothic,malgun gothic,dotum,arial,helvetica,MS Gothic,sans-serif!important">
안녕하세요, <strong th:text="${name}"></strong>!<br>
</td>
</tr>
<tr>
<td style="padding:0;line-height:1.5;font-family:AppleSDGothic,apple sd gothic neo,noto sans korean,noto sans korean regular,noto sans cjk kr,noto sans cjk,nanum gothic,malgun gothic,dotum,arial,helvetica,MS Gothic,sans-serif!important">
<div style="margin:40px 0 12px 0;line-height:1.5;font-size:21px;color:#000000;font-weight:bold">테스트</div>
</td>
</tr>
<tr>
<td style="color: #222;padding:0;line-height:1.5;font-family:AppleSDGothic,apple sd gothic neo,noto sans korean,noto sans korean regular,noto sans cjk kr,noto sans cjk,nanum gothic,malgun gothic,dotum,arial,helvetica,MS Gothic,sans-serif!important;font-size:16px">
<table cellpadding="0" cellspacing="0" border="0" width="100%" style="margin-bottom: 30px;border-top:1px solid #212121;border-bottom:1px solid #dddddd;table-layout:fixed;font-size:16px">
<tbody>
<tr>
<td style="width:150px;height:19px"></td>
<td style="height:19px"></td>
</tr>
<tr>

<td style="padding:5px 6px 5px 6px;color:#212121;text-align:left;font-weight:300;font-family: Roboto,RobotoDraft,Helvetica,Arial,sans-serif;" colspan="2"><strong style="color:#DD5555" th:text="${contents}"></strong></td>
</tr>

<tr>
<td style="width:150px;height:19px"></td>
<td style="height:19px"></td>
</tr>
</tbody>
</table>
<div style="margin:40px 0 0 0;text-align:center">
<a href="" style="display:inline-block;text-align:center;text-decoration:none" rel="noreferrer" target="_blank" data-saferedirecturl="https://www.google.com/url?q=https://www.talentbank.co.kr/common/project/projectViewContent?projectSeq%3D3587&amp;source=gmail&amp;ust=1641356798834000&amp;usg=AOvVaw3Ucuh2XzQLoFjRW8mGfHNH">
<span style="display:block;padding:12px 64px;background:#DD5555;border-radius:4px;line-height:28px;font-size:18px;color:#ffffff">사이트 바로가기</span>
</a>
</div>
</td>
</tr>
</tbody>
</table>
</td>
</tr>
</tbody>
</table>
</td>
</tr>
<tr>
<td style="padding:25px 10px 32px 10px;font-size:12px;background:#f1f1f1;color:#444;font-family:AppleSDGothic,apple sd gothic neo,noto sans korean,noto sans korean regular,noto sans cjk kr,noto sans cjk,nanum gothic,malgun gothic,dotum,arial,helvetica,MS Gothic,sans-serif!important">
<table cellpadding="0" cellspacing="0" border="0" width="100%" style="table-layout:fixed">
<tbody>
<tr>
<td style="padding:15px 0 0 0;font-size:14px;line-height:1.5;color:#707070">
<strong>Copyright © All Rights Reserved</strong>
</td>
</tr>
</tbody>
</table>
</td>
</tr>
</tbody>
</table>
</body>
</html>

(들여쓰기 이해바랍니다...)

 

6. Controller 생성

@RequestMapping("/mailSend")
public void mailSend(@RequestBody RequestMail requestMail) {

     requestMail.setTitle("테스트 메일"); // 제목
     requestMail.setSendTo(""); // 수신자 설정
     requestMail.setTemplates("test"); // 사용할 templates html 파일 이름

     Map mailMap = new HashMap();
     mailMap.put("name", "홍길동"); // 내용
     mailMap.put("contents", "테스트 메일 입니다."); // 내용

     requestMail.setContext(mailMap);

     try {
            emailService.sendMail(requestMail);
      } catch (Exception e) {
            log.error("email send error", e);
            throw new ServiceException();
      }

}

위와 같이 controller에서 설정해주고 넘겨주면 알아서 메일이 잘~~~보내진다.

* email을 보낼땐 try ~ catch 절로 예외처리가 필수이다.

혹은 메소드 자체에 throws를 붙여줘야한다.

 

 

7. 결과

 

 

728x90
반응형