메일 전송 1편 에 이어서
다시 한번 기억하기!
회원 등록이라는 이벤트가 발생하면 EventListener가 메일 전송 로직을 실행한다. 만약 메일 전송에 실패한다면 이미 데이터베이스에 저장된 회원 정보를 삭제하고, 회원 등록에 실패했다고 클라이언트에게 알려야 한다!
EventListener가 메일을 보내고, 실패할 경우 회원 정보를 삭제하는 로직을 구현하좌!
먼저 실패할 경우를 생각해보자면 실패란, 예외가 발생했다는 의미와 같다! 그러면 해당 예외를 잡아와서 처리하는 로직을 구현하면 되는 것! try-catch문
을 사용하면 쉽게 구현할 수 있다.
가보자고!👊
Member에 관한 비즈니스 로직을 처리하는 클래스를 MemberService
로 지칭하고 있다. 그러니 Mail에 관한 처리를 하는 비즈니스 계층의 클래스를 구현할 필요가 있다.
💡Google의 SMTP Server를 이용한다는 사실을 잊지 말기
Java에서 메일 쉽게 보낼 수 있도록 도와주는 API로서 MailSender 인터페이스를 상속 받은 인터페이스이다.
MailSender는 단순하고 간단하게 TEXT 메일만 전송할 수 있지만, JavaMailSender는 MIME 메세지까지 지원해 HTML로 작성된 메일도 보낼 수 있다.
그럼 메일을 보내기 위해 단순 String
이나 index.html
파일을 보내면 되는 것일까?🤔
MailMessage라는 별도의 클래스가 있다! 해당 클래스의 객체를 생성하고JavaMailSender의 send()
메서드에 담아 호출하면 application.yml
에 정의한 google smtp server
설정에 맞춰 메일을 보내준다.
MailMessage는 메일 메세지에 대한 일반적인 인터페이스로, 사용자가 해당 인터페이스를 사용하면 메일의 내용이 단순한 텍스트인지, MIME 메세지인지 파악하기 어렵기 때문에 MailMessage를 구현한 SimpleMailMessage와 MimeMailMessage를 사용한다.
단순한 메세지를 담아 보낼 때 사용한다.
MIME 메세지를 보낼 때 사용한다.
☝️🤓
아무튼 JavaMailSender를 MailService 클래스에 DI하여 사용한다! 그리고 여기서는
SimpleMailMessage를 사용하여 메일 전송 로직을 구현할 것!
간단하게 이렇게 4가지만 구성할 것이다. 그렇다면 이 정보들을 어디서 가져와야 할까? 이벤트 발신은 MemberEvent
클래스로 감싼 Member
객체를 담아 보냈다.
Member
객체를 메일 전송을 위해 변화시킬 필요가 있다!
단순히 이벤트로 받은 Member
객체를 메일 전송에 편리하게 사용하기 위해 변환하는 클래스, 메일 전송에 필요한 정보만을 담기 위한 클래스라고 생각하자.
사실 없어도 큰 문제는 없다...개발자의 편의를 위해 하나..?
이제 MailService의 메일 전송 메서드인 sendMail()
는 MailDto 객체를 받아 로직을 실행한다.
🧐 FROM_ADDRESS?
메일을 발송하는 주체는 애플리케이션의 관리자 메일일 것이다. 이를application.yml
파일에 환경 변수로 저장해두었기 때문에@Value
애너테이션을 사용하여 그 값을 가져온다.
이때@Value
애너테이션은org.springframework.beans.factory.annotation
에서 import된다.
Controller
에서 Service
의 메서드를 사용하기 위해서 Service
를 DI해왔다. 여기서도 마찬가지로 EventListener
에서 MailService
의 메서드를 사용하려면 DI를 해야 한다.
파라미터로 받은 MemberEvent
객체를 MailDto
객체를 생성해 MailService
의 sendMail()
메서드를 호출한다.
예외가 발생하면, 가입에 성공하지 못했다는 의미이므로 이미 MemberService.createMember()
에서 DB에 저장된 회원의 정보를 삭제해야 한다.
어떻게?🤔
MemberService.deleteMember()
를 사용하면 된다.☝️🤓
회원 정보를 삭제해준 뒤, 사용자 정의 타입의 예외를 던져주면 끝이다!! 뿌이뿌이뿌이🥳
사실 끝은 아니고 여러가지 에러가 발생했으나 구글 계정의 문제였으므로 따로 블로깅은 안하려고 한다...🙄
구글 계정의 비밀번호는 실질적인 비밀번호가 아닌 앱 비밀번호를 생성해서 사용하였다!
성공뿌이뿌이뿌이🥳