공공부하자개발 · 영어 학습 노트
자바
실무 확장Excel · 파일 업로드 · DB 연동0/22 완료
  • 01Excel(XLSX) 구조와 순수 JDK로 읽기/쓰기
  • 02Apache POI로 Excel 업로드/다운로드
  • 03파일 업로드/다운로드 서버 (HttpServer)
  • 04JDBC 기초와 트랜잭션 (H2)
  • 05MyBatis 어노테이션 매퍼로 쿼리 연동
  • 06MyBatis XML 매퍼 · Oracle 방언 · PageHelper · Spring Boot
  • 07REST API 서버와 JSON
  • 08Vue 3 SPA 와 Java 서버 연동
  • 09@Scheduled 운영
  • 10로깅 실무: 레벨·계층, MDC 추적, 예외·성능, 마스킹, 롤링, JSON 로그
  • 11외부 API 연동
  • 12테스트 실무
  • 13암호화·개인정보 보호
  • 14인코딩·한글 실무
  • 15@Transactional 심화
  • 16긴 작업 비동기 처리와 진행률
  • 17SFTP·FTP 파일 연계
  • 18로컬 캐시와 @Cacheable
  • 19메일·알림 발송
  • 20웹 보안 체크리스트
  • 21빌드 도구와 폐쇄망 의존성 반입
  • 22성능 측정: p50·p95·p99, 측정 계층, JFR, JMH 함정, 자체 부하 테스트, 병목 순위
사이트 소개개인정보처리방침연락처
© 2026 공부하자
홈 › 실무 확장 › 19 / 22

메일·알림 발송

SMTP 흐름, MIME·한글 제목·첨부, 실패 분류·재시도, 중복 방지, 알림 폭주 억제
섹션 7진행 0 / 22
1왜 배우는가2핵심 원리3코드 예제4응용 변형 예제5자주 하는 실수 (Tip)6연습 문제7정리‹ 이전다음 ›

4. 응용 변형 예제

4.1 Spring JavaMailSender 로 같은 메일 보내기

이 레슨의 SmtpClient 가 손으로 하는 일을 Spring 에서는 MimeMessageHelper 가 대신합니다.

java
@Autowired
private JavaMailSender mailSender;

public void sendReport(String to, byte[] csv) throws MessagingException {
    MimeMessage message = mailSender.createMimeMessage();
    MimeMessageHelper helper =
        new MimeMessageHelper(message, true, "UTF-8"); // true=멀티파트
    helper.setFrom("batch@company.co.kr");
    helper.setTo(to);
    helper.setSubject("9월 정산 리포트"); // 인코딩은 helper 가 처리
    helper.setText("첨부한 리포트를 확인해 주세요.");
    helper.addAttachment("정산리포트.csv", new ByteArrayResource(csv));
    mailSender.send(message);
}

RFC 2047 인코딩, multipart 조립, base64 변환을 라이브러리가 대신해 코드가 훨씬 짧습니다. 재시도·멱등키·폭주 억제 같은 정책은 이 레슨에서 다룬 대로 애플리케이션이 여전히 직접 챙겨야 합니다.

4.2 웹훅으로 장애 알림 보내기

java.net.http.HttpClient 로 사내 메신저 웹훅에 JSON 을 POST 합니다. notifyAlert 뒤에 실제 전송을 붙이면 됩니다.

java
private static void sendWebhook(String webhookUrl, String text) throws Exception {
    String json = "{\"text\":\"" + text.replace("\"", "\\\"") + "\"}";
    HttpClient client = HttpClient.newHttpClient();
    HttpRequest request = HttpRequest.newBuilder()
        .uri(URI.create(webhookUrl))
        .header("Content-Type", "application/json")
        .POST(HttpRequest.BodyPublishers.ofString(json, StandardCharsets.UTF_8))
        .build();
    client.send(request, HttpResponse.BodyHandlers.discarding());
}

메일과 웹훅을 같은 notifyAlert 안에서 함께 호출하면, 억제 로직 하나로 두 채널 모두 폭주를 막습니다.

4.3 요청 스레드 밖에서 대량 발송하기

@Async 로 컨트롤러 스레드와 발송 스레드를 분리합니다. 자세한 스레드 풀 설정은 16 번 레슨을 참고합니다.

java
@Async("mailExecutor")
public void sendBulk(List<String> recipients, String subject, String body) {
    for (List<String> chunk : partition(recipients, 150)) { // 150명씩 묶음
        for (String to : chunk) {
            trySend(to, subject, body); // 4xx 재시도·5xx 중단 포함
        }
        sleepQuietly(1000); // 릴레이 부하 분산
    }
}

컨트롤러는 이 메서드를 호출한 뒤 즉시 응답을 돌려주고, 실제 발송은 별도 스레드 풀에서 진행됩니다.

응용 변형 예제
  • 4.1 Spring JavaMailSender 로 같은 메일 보내기
  • 4.2 웹훅으로 장애 알림 보내기
  • 4.3 요청 스레드 밖에서 대량 발송하기
이전 섹션3 코드 예제4 / 7다음 섹션5 자주 하는 실수 (Tip)