스프링부트에서 메일을 보내야 할 필요가 생겼다.
개발하면서 필요했던 요구사항은 아래와 같다.
- 가입 환영 메일, 이메일 인증 메일, 기타 등등 여러 종류의 메일 발송 가능할것.
- 단순 텍스트 이메일이 아니라 html로 구성되어 디자인이 가능할 것.
- 코드가 복잡하지 않고 확장성 있을 것
열심히 찾아보던 중 thymeleaf라는 라이브러리를 찾게 되었다.
사용법이 간단해 공유해보고자 한다.
1. Maven dependency(pom.xml) 설정
<!-- 이메일 -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-mail</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-thymeleaf</artifactId>
</dependency>
2. src/main/resources/application.properties 설정
# 이메일 발송시 사용하는 html 템플릿 설정
## thymeleaf default settings
spring.thymeleaf.prefix=classpath:/mail-templates/ # 이메일 템플릿이 위치할 경로. classpath:를 통해 src/main/resources/ 밑으로 설정되었다.
spring.thymeleaf.suffix=.html # 템플릿 파일의 확장자
spring.thymeleaf.mode=HTML
spring.thymeleaf.encoding=UTF-8
spring.thymeleaf.check-template-location=true
## thymeleaf custom settings
spring.thymeleaf.cache=false
# 이메일 설정
## mail default settings
spring.mail.default-encoding=UTF-8
## mail custom settings
spring.mail.host=smtp.gmail.com
spring.mail.port=587
spring.mail.username={google email address}
spring.mail.password={email password}
spring.mail.properties.mail.smtp.auth=true
spring.mail.properties.mail.debug=true
spring.mail.properties.mail.smtp.starttls.enable=true
spring.mail.properties.mail.mime.charset=UTF-8
spring.mail.properties.mail.transport.protocol=smtp
메일 계정 정보를 직접 수정해주면 된다.
3. 보안 수준이 낮은 앱의 액세스 허용
아래 링크로 들어가 보안 수준이 낮은 앱 허용을 켜줘야 한다.
이 옵션을 켜지 않으면 구글에서 로그인을 차단하기 때문에 메일이 정상적으로 발송되지 않는다.
https://myaccount.google.com/lesssecureapps
4. src/main/resources/mail-templates/welcome.html 메일 템플릿 생성
<!DOCTYPE html>
<html lang="en" xmlns:th="http://www.thymeleaf.org">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
</head>
<body>
<span>가입을 환영합니다, </span>
<span th:text="${name}"></span>
<span>님</span>
</body>
</html>
위에서 application.properties 에 지정했던 폴더에 새로운 html 파일을 생성해주었다.
이 파일명이 추후에 호출할 템플릿 명이 된다.
5. 메일 class 생성
package me.huiya.core.Service;
import java.io.IOException;
import java.util.HashMap;
import javax.mail.MessagingException;
import javax.mail.internet.MimeMessage;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.mail.javamail.JavaMailSender;
import org.springframework.mail.javamail.MimeMessageHelper;
import org.springframework.stereotype.Component;
import org.thymeleaf.context.Context;
import org.thymeleaf.spring5.SpringTemplateEngine;
@Component
public class Email {
@Autowired
private JavaMailSender javaMailSender;
@Autowired
private SpringTemplateEngine templateEngine;
/**
* 이메일 발송 함수
* @param title 이메일 제목
* @param to 받는 사람
* @param templateName 이메일 템플릿
* @param values 이메일에 들어가는 값
* @throws MessagingException
* @throws IOException
*/
public void send(String title, String to, String templateName, HashMap<String, String> values) throws MessagingException, IOException {
MimeMessage message = javaMailSender.createMimeMessage();
MimeMessageHelper helper = new MimeMessageHelper(message, true);
//메일 제목 설정
helper.setSubject(title);
//수신자 설정
helper.setTo(to);
//템플릿에 전달할 데이터 설정
Context context = new Context();
values.forEach((key, value)->{
context.setVariable(key, value);
});
//메일 내용 설정 : 템플릿 프로세스
String html = templateEngine.process(templateName, context);
helper.setText(html, true);
//메일 보내기
javaMailSender.send(message);
}
}
함수를 하나 만들었는데, html 템플릿에 넣어줘야 하는 값을 HashMap으로 받도록 구성해서 같은 함수로 여러 템플릿을 발송할 수 있게 구성했다.
6. 코드 작성
@PostMapping(value="/signup")
public Result join(
@RequestParam(required = false) String email,
@RequestParam(required = false) String password,
@RequestParam(required = false) String nickName,
@RequestParam(required = false) String name,
) throws Exception {
Result result = new Result();
//
// 회원 가입 처리 (생략)
//
HashMap<String, String> emailValues = new HashMap<>();
emailValues.put("name", user.getName());
EmailService.send("가입을 환영합니다", user.getEmail(), "welcome", emailValues);
result.setSuccess(true);
result.setMessage(Type.OK);
return result;
}
기존에 쓰고 있던 회원가입 메소드 하단부에 메일 발송 함수를 추가해주었다.
함수 주석에도 달아놓았다시피 앞에서부터 차례대로
메일 제목, 받는 사람, 템플릿 명, 템플릿에 들어갈 값 목록을 넣어주면 된다.
7. 실행 결과
글에서는 별다른 디자인 없이 단순 텍스트로 테스트 메일을 구성하였지만 html 파일이라 추후 디자인이 나오는대로 템플릿을 수정해준다면 디자인된 메일을 발송할 수 있다.
그리고 html 템플릿 파일을 추가하고 함수 실행시에 값을 넘겨주기만 한다면 여러 종류의 메일도 발송 가능하다.
8. 추후 개선점
메일 발송은 속도가 느리기 때문에 실제 서비스에서 사용하기 위해서는 스레드를 이용해서 비동기적으로 메일을 보내야 한다.
다음글.
스레드를 이용해서 비동기로 메일 보내기
https://huiya-dev.tistory.com/15
출처
'개발 > Backend' 카테고리의 다른 글
[Spring Boot] 인터셉터 인증 처리 제외 어노테이션 만들기 (0) | 2021.07.15 |
---|---|
[Spring Boot] 작업 비동기로 실행하기 (2) | 2021.07.13 |
Access-Control-Allow-Origin을 넣어도 POST에서 CORS 에러가 발생할때 (0) | 2020.07.09 |
Apache start, stop 시 별도 스크립트 실행 (0) | 2019.06.21 |
Nginx + PHP 최신 버전 연동 (0) | 2019.06.21 |