기존 이메일 전송 기능을 개선해보고 싶었다.
이유
일단 구글 이메일 전송을 실패했던 이유는 구글은 운영 정책이 바뀌었는데 바뀌기 이전에 구현한 블로그들만 주구장창 시도해서였다.
"스프링 이메일 전송 구현"으로 검색하면 옛날 것만 떴는데
"javemailsender 사용법" 식으로 검색했더니 구글의 최신 정책을 반영해서 개발하는 법이 나와 있었다.
먼저 pom.xml에 mail 의존성 라이브러리를 추가한다.
https://noviceany.tistory.com/61
<dependency>
<groupId>com.sun.mail</groupId>
<artifactId>javax.mail</artifactId>
<version>1.6.2</version>
</dependency>
<dependency>
<groupId>org.apache.commons</groupId>
<artifactId>commons-email</artifactId>
<version>1.2</version>
</dependency>
root-context.xml에 javamailsender를 등록한다.
정보만 내 것으로 맞춰서 바꾸면 된다.
<bean id="mailSender" class ="org.springframework.mail.javamail.JavaMailSenderImpl" >
<property name="host" value="smtp.gmail.com" />
<property name="port" value="587" />
<property name="username" value="내 gmail계정 이메일" />
<property name="password" value="앱 비밀번호" />
<property name="javaMailProperties">
<props>
<prop key="mail.smtp.starttls.enable">true</prop>
</props>
</property>
</bean>
property중에 password 항목에 주의하자.
처음에는 그냥 내 구글 계정 비밀번호인 줄 알았는데
이메일 전송이 당최 안되는 것이다. 검색해보니 앱 비밀번호를 인증을 거쳐서 생성해서 그걸 써야 하는 것이었다...
아래 사이트를 참고해서 후다닥 만들어본다.
https://ivvve.github.io/2019/02/09/java/Spring/mail_AuthenticationFailedException/
그리고 스펠링이 틀리지 않았는 지 여러 번 확인한다.
나의 경우에는 1. 앱 비번을 제대로 안 써서 2. 이메일 스펠링 틀려서 오류가 발생했었다.
참고사이트
https://2-jissun.tistory.com/12
이제 코드를 짜 보자.
Email, EmailSender, EmailController 클래스를 생성했다.
package com.fastcampus.ch4.domain;
import lombok.Builder;
import lombok.Data;
@Data
@Builder
public class Email {
private String toEmail;
private String fromEmail;
private String title;
private String content;
}
이메일 객체 생성 시 좀 더 편하게 하려고 @Builder를 추가했다.
package com.fastcampus.ch4.service;
import com.fastcampus.ch4.domain.Email;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.mail.javamail.JavaMailSender;
import org.springframework.mail.javamail.MimeMessageHelper;
import org.springframework.stereotype.Service;
import javax.mail.internet.MimeMessage;
@Service
public class EmailSender {
@Autowired
private JavaMailSender mailSender;
//can not autowired라고 뜬다면 root-context.xml에 등록을 안 한 것이다.
public String sendMail(Email email) {
System.out.println("email = " + email);
try {
MimeMessage message = mailSender.createMimeMessage();
MimeMessageHelper messageHelper = new MimeMessageHelper(message, true, "UTF-8");
messageHelper.setTo(email.getToEmail());
messageHelper.setText(email.getContent());
messageHelper.setFrom(email.getFromEmail());
messageHelper.setSubject(email.getTitle()); // 메일제목은 생략이 가능하다
mailSender.send(message);
} catch(Exception e){
System.out.println(e);
return "Error";
}
return "Sucess";
}
}
javamailsender 등록을 root-context.xml에서 제대로 했다면, @Autowired가 문제없이 된다.
이제 controller에서 호출해보자.
package com.fastcampus.ch4.controller;
import com.fastcampus.ch4.domain.Email;
import com.fastcampus.ch4.service.EmailSender;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.GetMapping;
@Controller
public class EmailController {
@Autowired
EmailSender emailSender;
@GetMapping("/send/email")
public ResponseEntity<HttpStatus> getEmail(String toEmail) {
try {
Email email = Email.builder()
.fromEmail("jinvicky17@gmail.com")
.toEmail(toEmail)
.title("정석마켓 제목")
.content("키키키")
.build();
emailSender.sendMail(email);
} catch (Exception e) {
return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR).build();
}
return ResponseEntity.ok(HttpStatus.OK);
}
}
기존 이메일 전송 코드와 비교해봤다.
궁금?한 점
결과 화면