WEB/Spring & Spring boot

Spring boot와 SMTP로 이메일 발송 기능 구현하기

hyunah 2022. 1. 12. 12:33

 

졸업 프로젝트를 진행하면서 이메일 발송 기능을 맡아서 구현하였다. 생각 외로 까다롭지 않아서 구현하는데 그렇게 오랜 시간이 걸리지 않았다.

 

 

내가 구현하고자 했던 메일 발송 기능 프로세스는 다음과 같다.

 

  1. 사용자에게 이메일을 입력 받는다.
  2. 해당 이메일로 링크와 이미지가 포함된 메일을 발송한다.

 

회원가입/로그인 기능이 없는 웹에서 구현하는 것이었기에 OAuth, 세션 관련 처리를 해주지 않아도 되어서 매우 간단했다. 회원가입 인증 메일을 구현하고자 하는 사람에게는 이 글이 말하는 방법이 충분하지 않을 것이란 걸 미리 말해둔다.

 

 

 

 

1. build.gradle에 라이브러리 추가

 

 

build.gradle에 메일 관련 라이브러리를 먼저 추가한다.

 

 

 

 

 

2. properties(yml) 파일에 SMTP 서버 정보 추가

 

 

이때 username에는 메일을 전송하는 계정의 이메일을 입력하고 (예 : hhh111@gmail.com) password에는 해당 계정의 비밀번호를 입력한다. 이런 보안 정보는 깃허브에 올라가지 않도록 다시 한 번 주의하고 넘어가자.

smtp.auth=true : SMTP 서버의 auth 인증을 사용한다는 의미이다.

 

 

smtp.starttls.enable=true : 로그인시 TLS를 이용하겠다는 의미이다. TLS 외에 SSL도 있는데, 대부분의 메일 서비스라면 둘다 지원하지만 혹시 TLS로 해서 제대로 안 된다면 SSL로 바꿔서 다시 해보자. 그때는 포트번호를 465로 설정해주어야 한다.

 

 

 

 

 

3. 메일 기능 구현 코드 작성

3-1. MailHandler

JavaMailSender를 이용해 메일 메시지를 작성하고 직접 보내는 클래스다.

 

public class MailHandler {
    private JavaMailSender sender;
    private MimeMessage message;
    private MimeMessageHelper messageHelper;

    // 생성자
    public MailHandler(JavaMailSender jSender) throws
            MessagingException {
        this.sender = jSender;
        message = jSender.createMimeMessage();
        messageHelper = new MimeMessageHelper(message, true, "UTF-8");
    }

    // 송신자 이메일 추가
    public void setFrom(String fromAddress) throws MessagingException {
        messageHelper.setFrom(fromAddress);
    }

    // 수신자 이메일 추가
    public void setTo(String email) throws MessagingException {
        messageHelper.setTo(email);
    }

    // 제목 추가
    public void setSubject(String subject) throws MessagingException {
        messageHelper.setSubject(subject);
    }

    // 메일 내용 추가
    public void setText(String text, boolean useHtml) throws MessagingException {
        messageHelper.setText(text, useHtml);
    }

    // 첨부 파일 추가
    public void setAttach(String displayFileName, String pathToAttachment) throws MessagingException, IOException {
        File file = new File(ResourceUtils.getFile(pathToAttachment).getAbsolutePath());
        FileSystemResource fsr = new FileSystemResource(file);

        messageHelper.addAttachment(displayFileName, fsr);
    }

    // 이메일 발송
    public void send() {
        try {
            sender.send(message);
        }catch(Exception e) {
            e.printStackTrace();
        }
    }
}

 

 

3-2. MailService

MailHandler를 호출하는 서비스단의 코드다. 여기서 @AllArgsConstructor로 JavaMailSender에 값을 넣어주지 않으면 JavamailSender could be null과 같은 오류를 마주할 수 있다.

 

@AllArgsConstructor
@Service
public class MailService {
    private JavaMailSender mailSender;
    private static final String FROM_ADDRESS = "hhh1111@gmail.com";

    @Transactional
    public String sendMail(MailRequestDto requestDto) throws MessagingException {
        MailHandler mailHandler = new MailHandler(mailSender);

        mailHandler.setFrom(FROM_ADDRESS);
        mailHandler.setTo(requestDto.getRecipient());
        mailHandler.setSubject("메일 제목입니다.");

        String htmlContent = "<p> <img src = 'img링크' height='120' width='600'>\n</p>" +
                "<p><br/>텍스트.</p>";

        mailHandler.setText(htmlContent, true);

        mailHandler.send();
        return "success";
    }
}

 

Controller에서 MailService의 sendMail을 호출하는 코드를 추가하면 완성이다. 기능을 실행시켜보기 전에 거쳐야 하는 단계가 하나 더 있다.

 

 

 

 

 

4. 송신자 계정 설정

앞에서 계정 이름을 적고 비밀번호를 적어둔 계정에 접속하여 몇 가지 설정을 해주어야 한다. 그래야 원격으로 계정에 로그인이 되어 성공적으로 수신인에게 이메일이 발송될 수 있다. 내가 이용한 구글 메일 계정을 기반으로 설명하겠다.

 

 

설정 > 모든 설정 보기 > 전달 및 POP/IMAP > IMAP 사용

 

이메일 설정에 들어가서 IMAP 사용을 선택한다. IMAP과 POP, 그리고 SMTP에 대한 자세한 설명은 이곳에서 확인할 수 있다.

 

 

 

 

구글 계정 관리 > 보안 > 보안 수준이 낮은 앱의 액세스 허용

 

그 후에 구글 계정 설정에서 보안 수준이 낮은 앱의 액세스를 허용해주면 끝이다.