Spring Boot로 이메일 템플릿과 첨부파일 발송
Spring Boot에서 Thymeleaf 템플릿으로 HTML 메일을 생성하고 첨부파일을 함께 전송하는 전체 흐름을 설정부터 코드까지 단계별로 설명하는 예제
목차
소개
이 글은 Spring Boot에서 이메일을 HTML 템플릿으로 만들고 첨부파일을 함께 전송하는 방법을 초보자도 이해하기 쉽게 정리한다. Thymeleaf를 템플릿 엔진으로 사용하며, JavaMailSender로 MIME 메시지를 구성하는 과정을 포함한다. 실무에서 자주 쓰이는 설정과 코드 흐름을 중심으로 설명한다.
준비 사항
프로젝트는 Spring Boot 기반이며, 메일 전송을 위해 spring-boot-starter-mail과 Thymeleaf 의존성이 필요하다. 또한 메일 서버 정보(smtp)를 application.yml 또는 properties에 설정해야 한다.
의존성 (Maven)
<dependencies>
<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>
</dependencies>
application.yml 예시
spring:
mail:
host: smtp.example.com
port: 587
username: your@domain.com
password: yourpassword
properties:
mail:
smtp:
auth: true
starttls.enable: true
thymeleaf:
prefix: classpath:/templates/
suffix: .html
encoding: UTF-8
Thymeleaf 템플릿 준비
HTML 템플릿은 텍스트와 변수를 섞어 메일 본문을 만든다. templates 폴더에 예제를 둔다.
<!DOCTYPE html>
<html xmlns:th="http://www.thymeleaf.org">
<head>
<meta charset="UTF-8"/>
<title>메일 제목</title>
</head>
<body>
<h3>안녕하세요, <span th:text="${name}">회원</span>님</h3>
<p>아래 첨부파일을 확인해 주세요.</p>
</body>
</html>
메일 서비스 구현
핵심은 Thymeleaf로 HTML을 렌더링한 뒤 MimeMessageHelper로 본문과 첨부파일을 설정하는 것이다. 아래 코드는 서비스 계층 예시이다.
import org.springframework.core.io.FileSystemResource;
import org.springframework.mail.javamail.JavaMailSender;
import org.springframework.mail.javamail.MimeMessageHelper;
import org.thymeleaf.context.Context;
import org.thymeleaf.spring5.SpringTemplateEngine;
public class EmailService {
private final JavaMailSender mailSender;
private final SpringTemplateEngine templateEngine;
public EmailService(JavaMailSender mailSender, SpringTemplateEngine templateEngine) {
this.mailSender = mailSender;
this.templateEngine = templateEngine;
}
public void sendHtmlEmailWithAttachment(String to, String subject, String templateName, Map variables, File attachment) throws Exception {
Context context = new Context();
context.setVariables(variables);
String html = templateEngine.process(templateName, context);
javax.mail.internet.MimeMessage message = mailSender.createMimeMessage();
MimeMessageHelper helper = new MimeMessageHelper(message, true, "UTF-8");
helper.setTo(to);
helper.setSubject(subject);
helper.setText(html, true);
if (attachment != null && attachment.exists()) {
FileSystemResource resource = new FileSystemResource(attachment);
helper.addAttachment(attachment.getName(), resource);
}
mailSender.send(message);
}
}
핵심 설명
- TemplateEngine.process로 Thymeleaf 템플릿을 렌더링하여 HTML 문자열을 얻는다.
- MimeMessageHelper 생성 시 두 번째 파라미터를 true로 주면 multipart가 활성화되어 첨부파일 추가가 가능하다.
- helper.setText(html, true)로 HTML 본문을 설정한다.
- 첨부파일은 FileSystemResource 또는 InputStreamSource를 사용해 추가한다.
테스트 및 실행
로컬에서 테스트할 때는 메일서버 계정과 포트를 정확히 입력한다. 실제 운영에서는 발송량과 인증 여부, 대량 전송 정책을 확인해야 한다. 간단한 테스트는 스프링의 통합 테스트 또는 main 실행으로 확인 가능하다.
주의사항
- SMTP 인증과 TLS 설정이 올바른지 확인한다. 제공업체별 설정이 다를 수 있다.
- 첨부파일 크기 제한을 고려한다. 대용량 파일은 파일 서버 링크로 대체하는 편이 안전하다.
- 메시지 인코딩을 UTF-8로 맞추면 한글 깨짐을 방지할 수 있다.
- 템플릿에서 외부 리소스(CSS, 이미지)를 참조할 때는 절대 경로 또는 cid 방식을 검토한다.
맺음말
여러 라이브러리와 설정이 필요하지만, 순서대로 진행하면 구현이 어렵지 않다. 템플릿으로 본문을 관리하면 유지보수가 쉬워지고, 첨부파일 처리를 통해 다양한 요구에 대응할 수 있다. 필요한 경우 첨부파일을 바이트로 만들어 메모리에서 전송하는 방법이나, 대용량 전송을 위한 큐 기반 아키텍처로 확장하는 것을 고려한다.