[ Java ] 스프링에서 이메일 보내기 (JavaMailSenderImpl / MimeMessage)

2024. 6. 19. 13:45· LANGUAGE/└ Java

환경 : Spring Tool Sutie4

 

메일 발송 시 꼬옥~!!! 필요한 것?!?!?!

 

 

 

 

바로

 

 

 

 

 

메일 서버..

 

 

 

 

 

SMTP!!!!!!!!!!!!!

 

 

 

 

아무튼.. 예제와 함께 살펴보자.

메일 서버에 발신자의 메일 정보를 적어두어 메일을 보내는 방법이다

 

 

1. (공통) 메일 발송을 위한 의존성 추가 

    - pom.xml

<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-configuration-processor</artifactId>
    <optional>true</optional>
</dependency>
<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-mail</artifactId>
</dependency>

 


[ 1) 자바 한 페이지에서 메일 전송 ]

 

 (추가) 성공여부를 간단히 확인하기 위하여 스프링 테스트를 진행한다. 

 

스프링 테스트

  • 스프링에서 제공하는 테스트를 위한 도구들의 모음
  • 자바 진영에서는 JUnit이라는 압도적으로 유명한 테스트 도구가 존재
  • 스프링에서는 JUnit을 쓸 수 있도록 연결고리를 제공

 

 

   - SendMailTest01.java

@SpringBootTest//스프링 테스트 파일임을 표시(기존 환경과 연동됨)
public class SendMailTest01 {
	
	@Test //테스트 케이스임을 어노테이션으로 표시
	public void test() {
		
		//이메일을 전송하려면 전송도구가 필요 - Impl  사용
		JavaMailSenderImpl sender = new JavaMailSenderImpl();
        
		//필수정보 설정
		sender.setHost("smtp.gmail.com");//업체의 호스트 정보
		sender.setPort(587);//업체의 포트 번호
		sender.setUsername("계정");//계정
		sender.setPassword("비밀번호");//비밀번호
		
		//통신과 관련된 추가 설정//업체별(부가적) 추가 정보 설정 
		Properties props = new Properties();//자바에서 제공하는 문자열 Map
		props.setProperty("mail.smtp.auth", "true");//인증 후 이용 설정(필수)
		props.setProperty("mail.smtp.debug", "true");//디버깅 이용 설정(선택)
		props.setProperty("mail.smtp.starttls.enable", "true");//TLS 사용 설정(필수)
		props.setProperty("mail.smtp.ssl.protocols", "TLSv1.2");//TLS 버전 설정(필수)
		props.setProperty("mail.smtp.ssl.trust", "smtp.gmail.com");//신뢰할 수 있는 대상으로 설정(필수)
		sender.setJavaMailProperties(props);
		
		//메시지 생성
		SimpleMailMessage message = new SimpleMailMessage();
		
		message.setTo("받는사람");
		message.setCc("참조대상");
		message.setSubject("점심시간 10분 전");
		message.setText("오늘은 햄버거를 먹어요!!! 오예!@!!!!!");
		
		//전송
		sender.send(message);
	}
	
}

 

메시지의 정보를 넣는 메소드들은 아래와 같다.

message.setTo("받는사람1", "받는사람2", "받는사람3");
message.setCc("참조대상1", "참조대상2", "참조대상3");
message.setBcc("숨은참조대상1", "숨은참조대상2");
message.setSubject("제목");
message.setText("내용");

 

 

이렇게 하면 메일 전송이 된다~!!!


[ 2) 미리 만들어둔 도구를 불러와서 이메일을 발송 -  JavaMailSenderImpl ]

   - EmailConfriguration.java

이메일 전송시 필요한 정보 설정을 위한 클래스 파일

import java.util.Properties;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.mail.javamail.JavaMailSenderImpl;

//이메일 시스템에서 사용할 도구를 등록하기 위한 설정파일
@Configuration//설정파일로 등록하는 구문
public class EmailConfiguration {
	
	@Autowired
	private EmailProperties emailProperties;
	
	@Bean//스프링 빈(객체)으로 등록하는 구문
	public JavaMailSenderImpl sender() {
		//이메일을 전송하려면 전송도구가 필요하다
		JavaMailSenderImpl sender = new JavaMailSenderImpl();
		sender.setHost("smtp.gmail.com");//업체의 호스트정보
		sender.setPort(587);//업체의 포트 번호(gmail 포트 번호)
		sender.setUsername(emailProperties.getId());//계정
		sender.setPassword(emailProperties.getPw());//비밀번호
		
		//통신과 관련된 추가 설정
		Properties props = new Properties();//자바에서 제공하는 문자열 Map
		props.setProperty("mail.smtp.auth", "true");//인증 후 이용 설정(필수)
		props.setProperty("mail.smtp.debug", "true");//디버깅 이용 설정(선택)
		props.setProperty("mail.smtp.starttls.enable", "true");//TLS 사용 설정(필수)
		props.setProperty("mail.smtp.ssl.protocols", "TLSv1.2");//TLS 버전 설정(필수)
		props.setProperty("mail.smtp.ssl.trust", "smtp.gmail.com");//신뢰할 수 있는 대상으로 설정(필수)
		sender.setJavaMailProperties(props);
		
		return sender;
	}
	
}

   (+) 해당 이메일 설정을 하기 위해 가져온 EmailProperties는??

          - 메일을 보내는 사람의 계정 정보(아이디/비밀번호)를 매번 코드에 노출되게 사용할 수 없으므로 application.properties 파일에 보관해두고 가져와서 사용하는 방식이다. 

 

          - application.properties

# custom setting(email)
custom.email.id=계정아이디
custom.email.pw=계정비밀번호

        

         이 설정 파일을 매칭하여 값을 가져오기 위한 추가 설정이 필요하다

 

         - EmailProperties.java

import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.stereotype.Service;

//application.properties에 작성된 custom.email.어쩌구 설정을 담아두는 파일
@Service
@ConfigurationProperties(prefix = "custom.email")
public class EmailProperties {
	private String id;
	private String pw;
	
	public String getId() {
		return id;
	}
	public void setId(String id) {
		this.id = id;
	}
	public String getPw() {
		return pw;
	}
	public void setPw(String pw) {
		this.pw = pw;
	}
	
}

 

이를 이해하기 위한 그림

 

 

 

 

 설정해둔 파일들을 끌고와 메일이 전송되는지 테스트 해보자!

 

 

 

   - SendMailTest02.java

import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.mail.SimpleMailMessage;
import org.springframework.mail.javamail.JavaMailSenderImpl;

@SpringBootTest
public class SendMailTest02 {
	
	@Autowired
	private JavaMailSenderImpl sender;
	
	@Test
	public void test() {
		SimpleMailMessage message = new SimpleMailMessage();
		message.setTo("받는사람이메일 정보 입력");
		message.setSubject("테스트 제목");
		message.setText("테스트 내용");
		
		sender.send(message);
	}
}

 

 

성공~!!!


[ 3) 이메일 양식을 따로 보관하기 -  EmailService.java ]

 

   - EmailService.java

import java.util.Random;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.mail.SimpleMailMessage;
import org.springframework.mail.javamail.JavaMailSender;
import org.springframework.stereotype.Service;

@Service
public class EmailService {
	
	@Autowired
	private JavaMailSender sender;
	
	//가입 환영 이메일 발송
	public void sendWelcomeMail(String email) {
		SimpleMailMessage message = new SimpleMailMessage();
		message.setTo(email);
		message.setSubject("가입 환영!!");
		message.setText("앞으로 많은 활동 부탁드립니다!");
		
		sender.send(message);
	}
	
	//임시 비밀번호 발송
	public void sendTempPassword(String email) {
		String lower = "abcdefghijklmnopqrstuvwxyz";//3글자
		String upper = "ABCDEFGHIJKLMNOPQRSTUVWXYZ";//3글자
		String number = "0123456789";//1글자
		String special = "!@#$";//1글자
		
		Random r = new Random();//랜덤 도구
		StringBuffer buffer = new StringBuffer();//문자열 합성도구
		
		for(int i=0; i<3; i++) {
			int pos = r.nextInt(lower.length());//lower에서의 랜덤위치
			buffer.append(lower.charAt(pos));//버퍼에 추가
		}
		for(int i=0; i<3; i++) {
			int pos = r.nextInt(upper.length());//upper에서의 랜덤위치
			buffer.append(upper.charAt(pos));//버퍼에 추가
		}
		for(int i=0; i<1; i++) {
			int pos = r.nextInt(number.length());//number에서의 랜덤위치
			buffer.append(number.charAt(pos));//버퍼에 추가
		}
		for(int i=0; i<1; i++) {
			int pos = r.nextInt(special.length());//special에서의 랜덤위치
			buffer.append(special.charAt(pos));//버퍼에 추가
		}
		
		SimpleMailMessage message = new SimpleMailMessage();
		message.setText(email);
		message.setSubject("임시 비밀번호 안내");
		message.setText("임시 비밀번호는 " + buffer + "입니다.");
	}
	
	//인증번호 발송
	
}

 

 

먼저 환영 이메일 발송해보자

 

   - SendMailTest03.java

import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;

import com.kh.spring12.service.EmailService;

@SpringBootTest
public class SendMailTest03 {

	@Autowired
	private EmailService emailService;
	
	@Test
	public void test() {
		emailService.sendWelcomeMail("받는사람이메일 정보 입력");
	}
}

 

 

 

 

다음으로 임시 비밀번호 발행 메일을 보내보자 

 

 

   - SendMailTest04.java

import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;

import com.kh.spring12.service.EmailService;

@SpringBootTest
public class SendMailTest04 {

	@Autowired
	private EmailService emailService;
	
	@Test
	public void test() {
		emailService.sendTempPassword("받는사람이메일 정보 입력");
	}
}

 

 

정상적으로 작동함을 확인할 수 있다~~

 


 

다음으로 MIME MESSAGE 전송해보자!!!!!!

 

[ 1) 그냥 보내보기 (기본 이해) ]

   - MimeMessageTest01.java

import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.mail.javamail.JavaMailSender;
import org.springframework.mail.javamail.MimeMessageHelper;

import jakarta.mail.MessagingException;
import jakarta.mail.internet.MimeMessage;
import lombok.extern.slf4j.Slf4j;

@Slf4j
@SpringBootTest
public class MimeMessageTest01 {

	@Autowired
	private JavaMailSender sender;
	
	@Test
	public void test() throws MessagingException {
		//MimeMessage는 여러가지 옵션을 설정할 수 있는 메세지
		
		//메시지 객체 생성
		MimeMessage message = sender.createMimeMessage();
		
		//도우미 객체 생성 - 파일 전송은 안하고 UTF-8로 변환해서 전송하겠다
		//false : 나 파일은 안 보낸다
		MimeMessageHelper helper = new MimeMessageHelper(message, false, "UTF-8"); 
	
		//헬퍼에 정보를 설정
		helper.setTo(new String[] {"받을 사람 이메일 주소"});
		helper.setSubject("오늘의 운세");
//		helper.setText("<h1>안알랴줌!</h1>", true);//HTML 허용 설정
		
		
		//(주의) 발송되는 이메일에 들어갈 HTML 디자인은 전부다 인라인으로 작성
		StringBuffer buffer = new StringBuffer();
		buffer.append("<div style='padding:20px; box-shadow:0 0 2px 2px #ccc'>");
		buffer.append("<h1>당신의 오늘의 운세</h1>");
		buffer.append("<p>");
		buffer.append("안 알려 드립니다 -_^");
		buffer.append("</p>");
		buffer.append("</div>");
		
		helper.setText(buffer.toString(), true);
		
		//전송
		sender.send(message);
	}
}

 


[ 2) 보낼 메일 양식을 템플릿으로 저장하여 불러오기 ]

   - email-template.html

<div style="padding: 20px; border: 1px solid black;">
	<h1>오늘의 운세</h1>
	<p>안알랴줌! -_^</p>
</div>

    (+) 전송할 이메일 양식 작성 

    (+) 1번처럼 코드에 html 태그를 작성하는 것은 좋지 않음+사용성 높이기! 그래서 템플릿을 만들고 불러옴

 

   - MimeMessageTest02.java

import java.io.File;
import java.io.IOException;
import java.util.Scanner;

import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.core.io.ClassPathResource;
import org.springframework.mail.javamail.JavaMailSender;
import org.springframework.mail.javamail.MimeMessageHelper;

import jakarta.mail.MessagingException;
import jakarta.mail.internet.MimeMessage;
import lombok.extern.slf4j.Slf4j;

@Slf4j
@SpringBootTest
public class MimeMessageTest02 {

	@Autowired
	private JavaMailSender sender;
	
	@Test
	public void test() throws MessagingException, IOException {
		MimeMessage message = sender.createMimeMessage();
		
		MimeMessageHelper helper = new MimeMessageHelper(message, false, "UTF-8"); 
	
		helper.setTo(new String[] {"받을 사람 이메일 주소"});
		helper.setSubject("오늘의 운세");
		
		ClassPathResource resource = new ClassPathResource("templates/email-template.html");
		File target = resource.getFile(); //파일 추출
		
		StringBuffer buffer = new StringBuffer();//문자열 합성 도구 생성
		Scanner sc = new Scanner(target);//파일을 읽을 수 있는 도구 생성
		while(sc.hasNextLine()) { //읽을 수 있는 줄이 남아있다면 반복하여 실행
			buffer.append(sc.nextLine());//한 줄을 읽어 buffer에 추가
		}
		
		sc.close();
		
		helper.setText(buffer.toString(), true);//읽은 내용을 전송
		
		//전송
		sender.send(message);
	}
}

    (+) 템플릿 주소를 연결하여 파일을 추출.

    (+) 템플릿에 저장된 모든 정보를 읽어올 수 있도록 반복문 실행

 


[ 3) 링크 이동 ]

 

    - email-template2.html

<div style="padding: 20px; border: 1px solid black;">
	<h1>
		<span id="receiver">???</span>
		님 안녕하세요
	</h1>
	<p>
		오늘의 운세가 궁금하다면
		<a id="move-link" href="#">클릭</a>
	</p>
</div>

 

    - MimeMessageTest03.java

import java.io.File;
import java.io.IOException;
import java.util.Scanner;

import org.jsoup.Jsoup;
import org.jsoup.nodes.Document;
import org.jsoup.nodes.Element;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.core.io.ClassPathResource;
import org.springframework.mail.javamail.JavaMailSender;
import org.springframework.mail.javamail.MimeMessageHelper;

import jakarta.mail.MessagingException;
import jakarta.mail.internet.MimeMessage;
import lombok.extern.slf4j.Slf4j;

@Slf4j
@SpringBootTest
public class MimeMessageTest03 {

	@Autowired
	private JavaMailSender sender;
	
	@Test
	public void test() throws MessagingException, IOException {
		MimeMessage message = sender.createMimeMessage();
		
		MimeMessageHelper helper = new MimeMessageHelper(message, false, "UTF-8"); 
	
		helper.setTo(new String[] {"받을 사람 이메일 주소"});
		helper.setSubject("오늘의 운세");
		
		//내용을 외부 파일에서 불러와 전송하도록 구현
		ClassPathResource resource = new ClassPathResource("templates/email-template2.html");
		File target = resource.getFile(); //파일 추출
		
		StringBuffer buffer = new StringBuffer();//문자열 합성 도구 생성
		Scanner sc = new Scanner(target);//파일을 읽을 수 있는 도구 생성
		while(sc.hasNextLine()) { //읽을 수 있는 줄이 남아있다면 반복하여 실행
			buffer.append(sc.nextLine());//한 줄을 읽어 buffer에 추가
		}
		
		sc.close();
		
		//읽은 내용을 HTML로 해석해서 필요한 정보를 교체한 뒤 전송
		//-Jsoup 필요
		Document document = Jsoup.parse(buffer.toString());//HTML로 해석
		Element receiver = document.getElementById("receiver");//#receiver 탐색
		receiver.text("피카츄");//글자 설정
		
		Element link = document.getElementById("move-link");//#move-link 탐색
		link.attr("href", "https://www.google.com");
		
		helper.setText(document.toString(), true);//변환된 내용을 본문으로 설정
		
		//전송
		sender.send(message);
	}
}

 


[ 4) 이미지 추가 ]

이 예제의 경우 메일 사이트마다 이미지가 보일 수도 안 보일 수도 있다.

개발자도구로 태그가 잘 붙었는지 확인해보길 바람 

 

파일 첨부를 하기 위해선 Jsoup이 필요! → 의존성 추가

 

   - pom.xml

<!-- Jsoup : HTML 해석 도구 -->
<dependency>
    <groupId>org.jsoup</groupId>
    <artifactId>jsoup</artifactId>
    <version>1.17.2</version>
</dependency>

<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-configuration-processor</artifactId>
    <optional>true</optional>
</dependency>
<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-mail</artifactId>
</dependency>

 

  - MimeMessageTest04.java

import java.io.File;
import java.io.IOException;
import java.util.Scanner;

import org.jsoup.Jsoup;
import org.jsoup.nodes.Document;
import org.jsoup.nodes.Element;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.core.io.ClassPathResource;
import org.springframework.mail.javamail.JavaMailSender;
import org.springframework.mail.javamail.MimeMessageHelper;

import jakarta.mail.MessagingException;
import jakarta.mail.internet.MimeMessage;
import lombok.extern.slf4j.Slf4j;

@Slf4j
@SpringBootTest
public class MimeMessageTest04 {

	@Autowired
	private JavaMailSender sender;
	
	@Test
	public void test() throws MessagingException, IOException {
		MimeMessage message = sender.createMimeMessage();
		
		//도우미 객체 생성 - 파일 전송하면서 UTF-8로 변환해서 전송하겠다
		//true : 파일 보낼게
		MimeMessageHelper helper = new MimeMessageHelper(message, true, "UTF-8"); 
	
		helper.setTo(new String[] {"받을 사람 이메일 주소"});
		helper.setSubject("오늘의 운세");
		
		//내용을 외부 파일에서 불러와 전송하도록 구현
		ClassPathResource resource = new ClassPathResource("templates/email-template2.html");
		File target = resource.getFile(); //파일 추출
		
		StringBuffer buffer = new StringBuffer();//문자열 합성 도구 생성
		Scanner sc = new Scanner(target);//파일을 읽을 수 있는 도구 생성
		while(sc.hasNextLine()) { //읽을 수 있는 줄이 남아있다면 반복하여 실행
			buffer.append(sc.nextLine());//한 줄을 읽어 buffer에 추가
		}
		
		sc.close();
		
		//읽은 내용을 HTML로 해석해서 필요한 정보를 교체한 뒤 전송
		//-Jsoup 필요
		Document document = Jsoup.parse(buffer.toString());//HTML로 해석
		Element receiver = document.getElementById("receiver");//#receiver 탐색
		receiver.text("피카츄");//글자 설정
		
		Element link = document.getElementById("move-link");//#move-link 탐색
		link.attr("href", "https://www.google.com");
		
		helper.setText(document.toString(), true);//변환된 내용을 본문으로 설정
		
		//첨부파일 추가
		ClassPathResource attach1 = new ClassPathResource("static/image/bg.png");
		ClassPathResource attach2 = new ClassPathResource("static/image/user.png");
		//helper.addAttachment("이름", 리소스);
		helper.addAttachment(attach1.getFilename(), attach1);
		helper.addAttachment(attach2.getFilename(), attach2);
		
		//전송
		sender.send(message);
	}
}

 

 

 

 

 

개인 공부 기록용입니다:)

참고 : https://offbyone.tistory.com/167

 

728x90