- Today
- Total
개발하는 고라니
[Spring] 메일 송신 본문
Spring 프레임워크를 공부하던 도중, 문득 회원가입 시 E-mail 인증이 필요할 경우 서버에서 E-mail을 보내게 되는데,
이는 어떻게 작동하는건지 궁금해서 찾아보고 실습해보았다.
이메일 보내는 것을 하기 전, 간단히 메일 전송의 원리와 전자우편, 프로토콜에 대해 알아보았다.
메일 전송의 원리
- 사용자는 Mail Client와 같은 프로그램을 통해 메일을 작성 후, SMTP(Simple Mail Transfer Protocol)를 이용해 메일 데몬으로 메세지를 전송한다.
- 메일 데몬은 종단 간 Client의 주소를 분석하고 가장 가까운 (송신자 소속)Mail Server로 메세지와 정보를 넘긴다. (메일 데몬은 일종의 process로, 송신자의 메일과 정보를 메일 서버가 해석 가능하도록 가공한다.)
- 송신자가 보낸 메세지가 송신자 측의 전자우편을 관리하는 Mail Server에 전달되고, Mail Server는 수신자의 전자우편 주소를 분석해 최단경로를 찾아 근접한 Mail Server에 메세지를 전달한다.
- 최종 수신자 측의 Mail Server에 도착하기까지 연속적으로 전달하는 중계작업이 계속된다. 서로 근접한 Mail Server들 간에 전자우편을 계속해서 중계해 나가는 방법을 통해 메일을 "저장 후 전송"하는 서비스를 제공한다.
- 위와 같은 일련의 반복작업이 이뤄지면, 송수신자는 비로소 메일을 교환할 수 있게 된다.
전자우편의 주소체계와 구성
- E-mail은 @을 구분자로 좌측에 소속된 서버에서 부여받은 ID와 우측에 소속 서버 주소의 주소를 사용
- 전자우편은 [주소, 날짜, 주제(제목)]을 포함하는 메일 헤더와 메일의 [내용]이 포함된 메일 본체로 구성됨
Protocol
- SMTP(Simple Mail Transfer Protocol) : 일반적으로 메일을 송신할 때 사용된다. 이와 관련된 프로토콜에 대한 표준은 STD와 RFC에서 정하였다. 서버 to 서버로의 프로토콜이며, 이외의 다른 여러 프로토콜은 메세지를 접속하기위해 사용된다.
- POP(Post Office Protocol) : 인터넷 메일 Client가 메일 서버로부터 메일을 꺼내기 위한 규약이다. 인터넷에서 사실상 표준이 되어있다. 메일의 수신을 위한 프로토콜이며, 전자우편의 헤더와 본문 모두를 사용자의 컴퓨터로 다운로드한다. 이 프로토콜은 TCP 세션의 '109'번 포트를 쓰는데 최근 많이 사용되는 POP3는 110번 포트를 사용한다.
<-- ------------------------------------------------------------------------------------------------------------------------- -->
Spring으로 메일 보내기
* 메일을 보내려면 발송해주는 메일 서버(Mail Server)가 필요한데, 메일 서버를 통해 보낼 때 메일 서버에 접속하는 방법은 주로 2가지가 있다.
- 메일 서버에 계정이 있어서 ID/Password로 인증 후 메일을 보내는 경우(가장 일반적인 경우)
- 서버가 릴레이를 허용하는 경우(해당 메일 서버에 계정이 없어도 메일을 발송할 수 있다.)
본 포스트에서는 1번의 경우를 사용해 간단하게 메일의 제목과 본문을 보내는 작업을 수행해보겠다.
- 의존성 주입 (pom.xml)
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context-support</artifactId>
<version>5.0.7.RELEASE</version>
</dependency>
<!--javax.mail.Internet.MimeMessage를 사용하기 위한 Dependency -->
<dependency>
<groupId>com.sun.mail</groupId>
<artifactId>javax.mail</artifactId>
<version>1.6.2</version>
</dependency>
* Spring의 기본 메일 인터페이스는 MailSender인데, 이는 Spring의 SimpleMailMessage를 이용하며 첨부파일 등을 지원하지 않아 MIME Message를 이용하기로 한다.
- Bean 등록
mailSender를 빈으로 등록하기위해 root-context.xml에 등록하였으나 mail-context.xml을 따로 작성하여 등록해도 된다. 다음은 gmail서버를 이용해 메일을 보내기 위한 빈 등록이다.
<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="Account@gmail.com" />
<property name="password" value="Password" />
<property name="javaMailProperties">
<props>
<prop key="mail.smtp.auth">true</prop>
<prop key="mail.smtp.starttls.enable">true</prop>
</props>
</property>
</bean>
** 구글은 인증에 TLS를 사용하는데, TLS란 SSL과 같은 것이지만 SSL 3.0부터 TLS라 부른다.
- MailVO
@Data
public class MailVO {
private String subject;
private String text;
private String from;
private String to;
}
- MailController
@Controller
@Log4j
@RequestMapping("/mail")
public class MailController {
@Autowired
private JavaMailSenderImpl mailSender;
@GetMapping("/send")
public void send() {
log.info("===============================");
log.info("@Mail Controller, <GET> send");
}
@PostMapping("/send")
public ModelAndView send(MailVO vo, ModelAndView mv) {
mv.setViewName("/home");
log.info("@MailController, sendPost MailVO : " + vo);
final MimeMessagePreparator preparator = new MimeMessagePreparator() {
@Override
public void prepare(MimeMessage mimeMessage) throws Exception {
final MimeMessageHelper helper =
new MimeMessageHelper(mimeMessage, true, "UTF-8");
helper.setFrom(vo.getFrom());
helper.setTo(vo.getTo());
helper.setSubject(vo.getSubject());
helper.setText(vo.getText(), true);
}
};
mailSender.send(preparator);
return mv;
}
}
- send.jsp
<div class="form-email">
<form action="/mail/send" method="post">
<div class="standard-rectangle">
<label>수신자</label>
<input type="text" name="to">
</div>
<div class="standard-rectangle">
<label>메일 제목</label>
<input type="text" name="subject">
</div>
<div class="standard-rectangle">
<label>본문</label>
<textarea rows="8" cols="60" name="text"></textarea>
</div>
<div class="standard-rectangle">
<label>발신자</label>
<input type="text" name="from">
</div>
<div>
<input type="submit" class="submit" value="Submit">
</div>
</form>
</div>
간단하게 1. 메일을 받을 주소(To), 2.메일 제목(Subject), 3.본문(Text), 4.메일을 보내는 주소(From)을 입력해
POST 요청한다. 하지만 4.메일을 보내는 주소는 어떤 것을 입력하여도 Bean을 등록할 때 설정한 "Account@gmail.com"주소에서 보내진다.
중요한 것은 안티바이러스, 백신 프로그램은 종료 후에 시도해야 정상적으로 작동한다. 이를 켜두고 실행하면 500 Error가 발생한다.
'Framework > Spring' 카테고리의 다른 글
[Spring] 크롤링된 이미지 다운로드 (0) | 2020.12.16 |
---|---|
[Spring] 크롤링 해온 정보 DB에 저장 (0) | 2020.12.14 |
[Spring MVC] JSON 출력하기 (0) | 2020.12.08 |
[Spring MVC] @RestController String의 한글 처리 (0) | 2020.12.08 |
[Spring MVC] Web Socket(웹 소켓)과 Chatting(채팅) (11) | 2020.12.03 |