Spring Boot에서 SMTP로 HTML 메일 보내기 (Feat.Gmail)

무지성개발자·2025년 6월 15일
0

개요

픽블엽을 운영하면서 점점 유저들이 엽서를 등록해주기 시작했다.
엽서 등록 신청이 들어오면 관리자가 확인 후 승인(또는 거절)해주는 흐름인데, 지금까지는 신청한 유저가 결과를 알 수 없다는 단점이 있었다.

이 불편함을 개선하기 위해 메일 알림 기능을 도입하게 되었다.

SMTP

SMTP(Simple Mail Transfer Protocol)는 말 그대로 간단한 메일 전송 프로토콜이다.

이메일을 보낸다고 해서 바로 상대방 메일함에 도착하는 건 아니다.
이메일은 반드시 서버 간의 이동과 중계 절차를 거친다.
이때 메일을 전송하는 역할을 담당하는 것이 바로 SMTP다.

이메일의 흐름

예를 들어, user1@gmail.comuser2@naver.com에게 메일을 보낸다고 가정해보자.

  1. 사용자가 Gmail에서 메일을 작성
  2. Gmail 서버 → SMTP를 통해 메일 전송
  3. Naver 메일 서버 → POP3/IMAP으로 수신
  4. user2가 메일 클라이언트에서 확인

👉 메일을 보내는 역할은 SMTP,
👉 메일을 받는 역할은 POP3/IMAP

실전

GMAIL을 기준으로 설명한다.

✅ Step 0: 사전 준비

  • 2단계 인증 활성화
    Gmail SMTP는 2단계 인증이 활성화된 계정만 사용 가능하다.

  • 앱 비밀번호 생성
    메일 전송 시 Google 계정의 로그인 비밀번호 대신 앱 전용 비밀번호를 사용해야 한다.

✅ Step 1: 의존성 추가

dependencies {
    implementation 'org.springframework.boot:spring-boot-starter-mail'
}

Spring Boot의 JavaMailSender를 자동으로 등록해주는 의존성이다.

✅ Step 2: application.yml 설정

spring:
  mail:
    host: smtp.gmail.com
    port: 587
    username: your-email@gmail.com
    password: 앱 비밀번호
    properties:
      mail.smtp.auth: true
      mail.smtp.starttls.enable: true

📌 앱 비밀번호는 .env 외부 설정으로 분리하는 것이 좋다. 노출 절대 금지!

✅ Step 3: 간단한 메일 전송 클래스 만들기

@RequiredArgsConstructor
public class MailService {

    private final JavaMailSender mailSender;

    public void sendSimpleEmail(String to, String subject, String text) {
        SimpleMailMessage message = new SimpleMailMessage();
        message.setTo(to);								// 받는사람
        message.setSubject(subject);					// 메일 제목
        message.setText(text);							// 메일 본문
        message.setFrom("your-email@gmail.com");		// 보내는 사람

        mailSender.send(message);
    }
}

✅ Step 4: HTML 템플릿으로 메일 보내기(예시는 Thymeleaf사용)

템플릿 파일 (resources/templates/email.html)

<!DOCTYPE html>
<html xmlns:th="http://www.thymeleaf.org">
<head>
    <meta charset="UTF-8">
    <title>이메일 제목</title>
</head>
<body>
    <h2 th:text="${title}">기본 제목</h2>
    <p th:text="${message}">기본 메시지</p>

    <table border="1" cellpadding="5">
        <tr><td>이름</td><td th:text="${name}">홍길동</td></tr>
        <tr><td>이메일</td><td th:text="${email}">email@example.com</td></tr>
    </table>
</body>
</html>
@Service
@RequiredArgsConstructor
public class MailService {

    private final JavaMailSender mailSender;
    private final TemplateEngine templateEngine;

    public void sendTemplatedMail(String to, String subject, String name, String email) throws MessagingException {
        // Thymeleaf context 설정
        Context context = new Context();
        context.setVariable("title", "이메일 제목");
        context.setVariable("message", "이메일 메시지");
        context.setVariable("name", name);
        context.setVariable("email", email);

        // 템플릿 렌더링
        String html = templateEngine.process("email", context); // email.html 사용

        // 메일 전송 준비
        MimeMessage message = mailSender.createMimeMessage();
        MimeMessageHelper helper = new MimeMessageHelper(message, true, "UTF-8");

        helper.setTo(to);
        helper.setSubject(subject);
        helper.setFrom("your-email@gmail.com");
        helper.setText(html, true); // HTML 메일로 전송

        mailSender.send(message);
    }
}

Thymeleaf 템플릿엔진을 사용할 때 Controller에서 Model에 실어 보낸 정보를 context에 담아서 정보를 전달한다.
templateEngine.process(...)는 .html 확장자를 자동으로 붙이며, 기본 경로는 resources/templates/이다.
다른 경로라면 mail/이메일.html처럼 경로 포함해 작성 가능하다.

결론

이렇게 하면 Gmail SMTP를 통해 하루 500건 한도 내에서 무료로 메일 전송이 가능하며 현재 픽블엽의 규모에서는 충분히 커버 가능한 수준이라 이 기능만으로도 잘 돌아가고 있다.
SMTP는 빠르게 메일 전송 기능을 붙이기에 좋은 선택이다. 때문에 픽블엽에서는 알림용도로 적극 활용할 생각이다.

번외. 유료 메일 서비스

향후 서비스가 성장하거나, 메일 트래픽이 많아지면 다음과 같은 유료 메일 전송 서비스도 고려할 수 있다.

서비스특징
SendGrid대량 메일 발송, 마케팅 이메일, A/B 테스트 지원
Amazon SES저렴한 가격, AWS 인프라와의 강력한 통합
Mailgun트랜잭션 메일 특화, 분석 기능 제공

유저에게 이메일 전송을 할 땐 HTML 템플릿을 쓰면 메일의 품질과 일관성이 좋아지니 반드시 적용하는게 좋다고 생각한다.

profile
no-intelli 개발자 입니다. 그래도 intellij는 씁니다.

0개의 댓글