[Spring] smtp 사용해서 이메일 보내기
간이 전자 우편 전송 프로토콜(Simple Mail Transfer Protocol, SMTP)은 인터넷에서 이메일을 보내기 위해 이용되는 프로토콜이다. 사용하는 TCP 포트번호는 25번이다. 상대 서버를 지시하기 위해서 DNS의 MX레코드가 사용된다. RFC2821에 따라 규정되어 있다. 메일 서버간의 송수신뿐만 아니라, 메일 클라이언트에서 메일 서버로 메일을 보낼 때에도 사용되는 경우가 많다.
1. 이메일 전송 서버로 사용할 구글 계정을 준비한다.
case1) 2단계 인증을 사용 안하는 계정일 경우
https://www.google.com/settings/security/lesssecureapps
여기에서 '보안 수준이 낮은 앱의 액세스' 를 '사용'상태로 변경해준다.
case2) 2단계 인증을 사용하는 계정일 경우
1) 구글 계정 관리 클릭
2) 보안 > 앱 비밀번호 클릭
3) 메일, Windows컴퓨터로 선택 후 생성 클릭
4) Windows 컴퓨터용 앱 비밀번호 내용을 복사 후 메모장에 저장해둔다.
5) 구글 메일에서 설정 아이콘 클릭 > 모든 설정 보기 클릭
6) 전달 및 POP/IMAP 메뉴 클릭 > 모든 메일에 POP사용하기, IMAP사용 설정 후 '변경사항 저장'클릭
1. pom.xml에 관련 라이브러리를 추가한다.
<dependency>
<groupId>javax.mail</groupId>
<artifactId>mail</artifactId>
<version>1.4.7</version>
</dependency>
2. root-context.xml 에 bean을 추가한다.
case1) 2단계 인증을 사용 안하는 계정일 경우
아이디: 이메일 전송 서버로 사용할 구글 계정 / 비밀번호: 계정비밀번호
case2) 2단계 인증을 사용하는 계정일 경우
아이디: 이메일 전송 서버로 사용할 구글 계정 / 비밀번호: 메모장에 저장해둔 Windows 컴퓨터용 앱 비밀번호
<!-- 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="구글아이디"/>
<property name="password" value="비밀번호"/>
<property name="javaMailProperties">
<props>
<prop key="mail.smtp.starttls.enable">true</prop>
<prop key="mail.smtp.auth">true</prop>
<prop key="mail.transport.protocol">smtp</prop>
<prop key="mail.debug">true</prop>
<prop key="mail.smtp.ssl.trust">smtp.gmail.com</prop>
<prop key="mail.smtp.ssl.protocols">TLSv1.2</prop>
</props>
</property>
</bean>
<prop key="mail.smtp.ssl.protocols">TLSv1.2</prop>
이 두줄을 명시하지 않으면 TLS 버전이 기존 지원이 중단된 TLS 버전 1.0 이나 1.1으로 사용되는 예외가 있어 문제가 발생한다. (javax.mail.MessagingException 발생)구 버전인 TLS 1.0, 1.1 은 POODLE 과 BEAST 와 같은 여러 공격에 취약한 이유로 2020년 이후부터 주요 브라우저에서는 지원을 중단했다.
따라서 1.2버전을 사용하겠다는 지정이 필요하다.
3. 메일 전송 기능 관련 개발 (jsp, controller, service, serviceImpl)
1) mailTest.jsp개발 (jquery, bootstrap 사용)
<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%>
<jsp:include page="/WEB-INF/jsp/common/header.jsp" />
<style>
#mailForm {
margin-top:20px;
}
</style>
<div id="mailForm" class="row justify-content-center">
<div class="col-8">
<div class="form-group">
<label for="recipient">받는사람</label>
<input name="email" type="email" class="form-control" id="recipient" placeholder="name@example.com">
</div>
<div class="form-group">
<label for="title">제목</label>
<input name="title" type="text" class="form-control" id="title" placeholder="메일제목">
</div>
<div class="form-group">
<textarea name="contents" class="form-control" id="contents" rows="10"></textarea>
</div>
<button id="mailSend" class="btn btn-primary">보내기</button>
</div>
</div>
<script type="text/javascript">
$(document).ready(function() {
$(document).on('click', '#mailSend', function() {
mailSend();
});
});
function mailSend() {
var recipient = $('#recipient').val();
var title = $('#title').val();
var contents = $('#contents').val();
var regex = new RegExp("([!#-'*+/-9=?A-Z^-~-]+(\.[!#-'*+/-9=?A-Z^-~-]+)*|\"\(\[\]!#-[^-~ \t]|(\\[\t -~]))+\")@([!#-'*+/-9=?A-Z^-~-]+(\.[!#-'*+/-9=?A-Z^-~-]+)*|\[[\t -Z^-~]*])");
if(!regex.test(recipient)) {
alert("이메일 주소를 올바르게 입력해주세요.");
return false;
} else if(title.replace(/\s/g, "") == "") {
alert("제목을 입력해주세요.");
return false;
} else if(contents.replace(/\s/g, "") == "") {
alert("내용을 입력해주세요.");
return false;
}
var params = {};
params.recipient = $('#recipient').val();
params.title = title;
params.contents = contents;
$.ajax({
method: "POST"
,url: "/mailTest/send"
,dataType : "json"
,data: JSON.stringify(params)
,contentType: "application/json; charset=UTF-8"
,success: function(data){
console.log(data);
}
,error : function(jqXHR, textStatus, errorThrown){
console.log("에러...");
}
});
}
</script>
</body>
</html>
2) mailController.java 개발
package com.research.spring.controller;
import java.util.Locale;
import java.util.Map;
import javax.servlet.http.HttpServletRequest;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.servlet.ModelAndView;
import com.google.gson.Gson;
import com.research.spring.service.mailService;
@Controller
public class mailController {
private static final Logger log = LoggerFactory.getLogger(mailController.class);
@Autowired
mailService mailService;
@RequestMapping(value = "/mailTest", method = RequestMethod.GET)
public ModelAndView quartzTest(Locale locale, Model model) {
ModelAndView mav = new ModelAndView();
mav.setViewName("jsp/mailTest");
return mav;
}
@ResponseBody
@RequestMapping(value = "/mailTest/send", method= {RequestMethod.POST}, produces = "application/json; charset=UTF-8")
public String vscstrt_call_save_editing(@RequestBody Map<String, Object> params, HttpServletRequest req) {
int result = 0;
Gson gson = new Gson();
log.info(params.toString());
try {
mailService.sendSingle(params);
params.clear();
params.put("status", "000");
params.put("msg", "성공");
} catch (Exception e) {
params.clear();
params.put("status", "-100");
params.put("msg", "실패");
}
return gson.toJson(params);
}
}
3) mailService.java 개발
package com.research.spring.service;
import java.util.Map;
public interface mailService {
public void sendSingle(Map<String, Object> params);
}
4) mailServiceImpl.java 개발
mimeMessage.setFrom : 보내는사람. '이메일 전송 서버로 사용할 구글 계정'을 입력해준다.
보낸사람타이틀을 넣으면 아래와 같이 메일이 보내지게 된다.
예시) 보낸사람타이틀을 '이메일테스트'로 입력
mimeMessage.addRecipient : 받는사람.
mimeMessage.setSubject : 메일제목.
mimeMessage.setContent : 메일내용. html형식으로 string을 넣을시 메일에 모양이 그대로 적용된다.
* <pre></pre> 태그 안에 메일내용을 넣으면 띄워쓰기, 줄바꿈 등이 그대로 적용되어 보내진다.
package com.research.spring.service.impl;
import java.util.Map;
import javax.mail.internet.InternetAddress;
import javax.mail.internet.MimeMessage;
import javax.mail.internet.MimeMessage.RecipientType;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.mail.javamail.JavaMailSender;
import org.springframework.stereotype.Service;
import com.research.spring.service.mailService;
@Service
public class mailServiceImpl implements mailService{
private static final Logger log = LoggerFactory.getLogger(mailServiceImpl.class);
@Autowired
private JavaMailSender mailSender;
@Override
public void sendSingle(Map<String, Object> params) {
String recipient = params.get("recipient").toString();
String title = params.get("title").toString();
String contents = params.get("contents").toString();
String htmlText = "";
log.info(params.toString());
try {
MimeMessage mimeMessage = mailSender.createMimeMessage();
mimeMessage.setFrom(new InternetAddress(구글아이디, 보낸사람타이틀, "utf-8"));
mimeMessage.addRecipient(RecipientType.TO, new InternetAddress(recipient));
mimeMessage.setSubject(title, "utf-8");
htmlText = "<div id=\"mailView\" style=\"background-color: #f9f9f9;padding: 40px;\">\r\n" +
" <pre style='margin-top:0;margin-bottom:20px;'>" +
contents +
" </pre>" +
" <a href=\"https://kje1218.tistory.com/\" target=\"_blank\" style=\"\r\n" +
" text-decoration-line:none;text-decoration-line:none;display:inline-block;padding:10px 20px;color:black;background-color:#e1e1e1;border-radius:5px;\">블로그 바로가기</a>\r\n" +
" \r\n" +
"</div>";
mimeMessage.setContent(htmlText, "text/html; charset=utf-8");
mailSender.send(mimeMessage);
} catch (Exception e) {
e.printStackTrace();
}
}
}
5) 결과 확인
https://m.blog.naver.com/PostView.naver?isHttpsRedirect=true&blogId=software705&logNo=220658726304
https://ajdahrdl.tistory.com/236
https://heestory217.tistory.com/124