참조 문서
목적 및 개요
프로젝트를 진행하던 중에 회원에게 메일을 발송하는 기능을 구현해야겠다는 생각이 들었다.
회원가입 시 이메일 인증을 하고, 비밀번호를 분실했을 때 임시 비밀번호를 발송하는 기능을 구현하였다.
메일을 발송하는 방법은 여러가지가 있지만 Gmail의 SMTP 서버를 활용하여 이메일을 발송하는 방법을 이용하여 기능을 구현해보았다.
개발 환경
- Spring Boot 3.1.8
- Java 17
- eclipse
구글 계정 설정
Gmail의 SMTP 서버를 활용하기 위한 절차가 필요하다.
- 구글 계정 관리에 들어가서 보안 탭을 클릭한다.
- 2단계 인증을 설정하지 않았다면 사용하는 것으로 설정을 변경한다.
- 아래 이미지를 참고하여 앱 비밀번호를 설정한다.
- 앱 선택 목록에서 메일을 선택한다.
- 기기 선택 목록에서 기타를 선택한 후 기기 이름을 입력한다(원하는대로 작성).
- 생성 버튼을 눌러 앱 비밀번호를 생성한다.
- 16자리의 앱 비밀번호를 확인합니다. 앱 비밀번호는 노출되지 않도록 주의하고, 개인 공간에 복사해둔다.
- 확인버튼을 눌러 완료한다.
구글 메일 설정
- Gmail 설정에 들어가서 전달 및 POP/IMAP 탭으로 들어간다.
- 모든 메일에 POP를 활성화 하기를 선택한다.
- IMAP 사용을 선택한다.
- 변경사항을 저장한다.
의존성 & yml 파일 설정
build.gradle 수정
dependencies {
...
implementation 'org.springframework.boot:spring-boot-starter-mail'
...
}
- Spring Boot Starter Mail: 메일서버와 연결해서 메일을 발송하는데 필요한 라이브러리
application.yml 수정
spring:
mail:
host: smtp.gmail.com # 1
port: 587 # 2
username: # 3
password: # 4
properties:
mail:
smtp:
auth: true # 5
timeout: 5000 # 6
starttls:
enable: true # 7
- SMTP 서버 호스트
- SMTP 서버 포트
- SMTP 서버 로그인 아이디: 발신자 (이메일이 test@gmail.com 이면 test가 해당)
- SMTP 서버 로그인 패스워드: 앱 비밀번호
- 사용자 인증 시도 여부 (기본값 : false)
- Socket Read Timeout 시간(ms) (기본값 : 무한대)
- StartTLS 활성화 여부 (기본값 : false)
Config 설정
package com.example.study.config;
import java.util.Arrays;
import java.util.Properties;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.mail.javamail.JavaMailSender;
import org.springframework.mail.javamail.JavaMailSenderImpl;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;
@Configuration
public class Config implements WebMvcConfigurer {
@Bean
public JavaMailSender javaMailSender() {
JavaMailSenderImpl jms = new JavaMailSenderImpl();
// 아래의 설정은 .yml 파일에 있는 설정을 그대로 대입하면 된다!
jms.setHost("smtp.gmail.com"); // smtp 기본 설정(그대로 넣으면 됨)
jms.setPort(587); // 지메일 서버가 사용하는 포트 번호
jms.setUsername(""); // 내가 설정한 발신 이메일
jms.setPassword(""); // 앱 비밀번호
Properties properties = new Properties(); // 속성 정보를 담는 객체
properties.setProperty("mail.transport.protocol", "smtp");
properties.setProperty("mail.smtp.auth", "true");
properties.setProperty("mail.smtp.timeout", "5000");
properties.setProperty("mail.smtp.starttls.enable", "true");
jms.setJavaMailProperties(properties);
return jms;
}
}
DTO 설정
import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Data;
import lombok.NoArgsConstructor;
@Data
@AllArgsConstructor
@NoArgsConstructor
@Builder
public class MailDTO {
private String address;
private String title;
private String message;
}
SERVICE 설정
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.mail.SimpleMailMessage;
import org.springframework.mail.javamail.JavaMailSender;
import org.springframework.stereotype.Service;
import com.example.study.mail.dto.MailDTO;
import lombok.extern.slf4j.Slf4j;
@Slf4j
@Service
public class MailService {
@Autowired
private JavaMailSender javaMailSender;
// 실제 이메일 보내기
public void mailSend(MailDTO mailDto ,String reply) {
SimpleMailMessage message = new SimpleMailMessage();
message.setTo(mailDto.getAddress());
message.setSubject(mailDto.getTitle());
message.setText(mailDto.getMessage());
message.setFrom("");
message.setReplyTo(reply);
javaMailSender.send(message);
}
}
CONTROLLER 설정
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;
import org.springframework.web.bind.annotation.RequestParam;
import com.example.study.mail.dto.MailDTO;
import com.example.study.mail.service.MailService;
import lombok.extern.slf4j.Slf4j;
@Controller
@Slf4j
public class MailController {
@Autowired
MailService mailService;
@GetMapping("/send-email")
public ResponseEntity<?> sendEmail() {
MailDTO dto = MailDTO.builder()
.address("아무렇게나")
.message("가능하겠죠")
.title("하하ㅏ하핳ㅎ")
.build();
mailService.mailSend(dto, "하하하핳ㅎ");
return new ResponseEntity("완료",HttpStatus.OK);
}
}
'SpringBoot' 카테고리의 다른 글
Springboot - @JsonNaming , @JsonProperty json 형식에 코딩 컨벤션의 스네이크 케이스를 카멜 노이션으로 변경하기 (0) | 2024.02.06 |
---|---|
Springboot - OAuth 2.0(Open Authorization) 인증 방식의 이해 (1) | 2024.02.06 |
Springboot - Server to Server RestTemplate (0) | 2024.02.05 |
Springboot - HandlerInterceptor (1) | 2024.02.02 |
Springboot - @RequestBody 와 @ModelAttribute 의 차이점 (0) | 2024.01.30 |