이제 자바로 이메일 전송을 하는 방법을 코드로 짜볼려고한다
스프링에서 실습하기전에 먼저 JSP 로 실습을 해보았다.
먼저 구글에 로그인하고 보안에 2단계 인증 클릭
맨 밑을 보면 앱 비밀번호가 있는데 해당 선택박스 선택후 생성클릭
그럼 임시 비밀번호가 뜨는데 한번만 가르쳐주니깐 꼭 저장하자
필요한 jar 파일을 다운받고
해당 폴더에 복사하고 붙여넣고 Bulid Path 해주자
그럼 이메일 발송 준비는 마쳤다.
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Insert title here</title>
</head>
<body>
<h1>자바 메일 전송 폼</h1>
<form action="SendMailPro" method="post">
<table border="1">
<tr>
<th>보내는 사람</th>
<td><input type="text" name="sender"></td>
</tr>
<tr>
<th>받는 사람</th>
<td><input type="text" name="receiver"></td>
</tr>
<tr>
<th>제목</th>
<td><input type="text" name="title"></td>
</tr>
<tr>
<th>내용</th>
<td><textarea name="content" rows="5" cols="20"></textarea></td>
</tr>
<tr>
<td colspan="2"><input type="submit" name="메일발송"></td>
</tr>
</table>
</form>
</body>
</html>
뷰페이지를 생성하고
@WebServlet("/SendMailForm")
public class SendMailFormServlet extends HttpServlet {
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
RequestDispatcher dispatcher =
request.getRequestDispatcher("jsp15_java_mail/mail_form.jsp");
dispatcher.forward(request, response);
}
}
뷰페이지와 매핑을 해주고
// 자바 메일 기능 사용 시 메일 서버(ex. Gmail 등) 인증을 위한 정보 관리 용도의
// javax.mail.Authenticator 클래스를 상속받는 서브클래스 정의
public class GoogleMailAuthenticator extends Authenticator {
// 인증 정보(아이디, 패스워드(앱비밀번호))를 관리할
// javax.mail.PasswordAuthentication 타입 변수 선언
private PasswordAuthentication passwordAuthentication;
// 기본 생성자 정의
public GoogleMailAuthenticator() {
passwordAuthentication = new PasswordAuthentication("ytlee7066", "ryncyuyvdqttnfax");
}
@Override
protected PasswordAuthentication getPasswordAuthentication() {
return passwordAuthentication;
}
}
--------------------------코드 분석-------------------------
public class GoogleMailAuthenticator extends Authenticator
- 자바 메일 기능 사용 시 메일 서버(ex. Gmail 등) 인증을 위한 정보 관리 용도의
javax.mail.Authenticator 클래스를 상속받는 서브클래스 정의
private PasswordAuthentication passwordAuthentication;
- 인증 정보(아이디, 패스워드(앱비밀번호))를 관리할
javax.mail.PasswordAuthentication 타입 변수 선언
public GoogleMailAuthenticator() {
passwordAuthentication = new PasswordAuthentication("ytlee7066", "ryncyuyvdqttnfax");
}
인증에 사용될 아이디와 패스워드를 갖는 PasswordAuthentication 객체 생성
- 파라미터 : 메일 서버 계정명, 패스워드(구글에서 받은 그 패스워드)
- Gmail 기준 2단계 인증 미사용 시 : Gmail 계정명, 패스워드 전달
"" 사용 시 : Gmail 계정명, 2단계 인증 우회 앱비밀번호 전달
(구글 계정 설정 - 보안 - 2단계 인증 - 앱 비밀번호 설정 필요)
(생성 항목 : 앱선택 = 메일, 기기 선택 = Windows 컴퓨터)
=> 생성 완료 시 나타나는 앱 비밀번호를 패스워드 대신 사용
@Override
protected PasswordAuthentication getPasswordAuthentication() {
return passwordAuthentication;
}
인증 정보 관리하는 객체(PasswordAuthentication)를 외부로 리턴하는
getPasswordAuthentication() 메서드 정의
=> 주의! Getter 메서드 정의 시 변수명에 따라 메서드명이 달라질 수 있음
또한, 외부에서 getPasswordAuthentication() 메서드를 직접 호출하지 않음
=> Authenticator 클래스 내부의 getPasswordAuthentication() 메서드 오버라이딩 할 것!
@WebServlet("/SendMailPro")
public class SendMailProServlet extends HttpServlet {
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
// System.out.println("SendMailProServlet");
// mail_form.jsp 페이지로부터 전달받은 폼 파라미터 가져와서 확인
request.setCharacterEncoding("UTF-8");
String sender = request.getParameter("sender");
String receiver = request.getParameter("receiver");
String title = request.getParameter("title");
String content = request.getParameter("content");
// System.out.println(sender + ", " + receiver + ", " + title + ", " + content);
try {
// --------------- 메일 전송에 필요한 정보 설정 작업 ---------------
// 1. 시스템(현재 서버 = 톰캣)의 속성 정보(= 서버 정보)를 관리하는 객체를
Properties properties = System.getProperties();
// 2. Properties 객체를 활용하여 메일 전송에 필요한 기본 정보를 서버 정보에 추가
// => put() 메서드 활용
properties.put("mail.smtp.host", "smtp.gmail.com"); // 구글(Gmail) SMTP 서버 주소
properties.put("mail.smtp.auth", "true"); // SMTP 서버 접근 시 인증 여부 설정
properties.put("mail.smtp.port", "587"); // Gmail 서버의 서비스 포트 설정(TLS)
// 메일 서버 인증 관련 추가 정보 설정(설정 내용에 따라 port 정보가 바뀜)
properties.put("mail.smtp.starttls.enable", "true"); // TLS 라는 인증 프로토콜 사용 여부 설정
properties.put("mail.smtp.ssl.protocols", "TLSv1.2"); // TLS 인증 프로토콜 버전 설정
// 만약, 메일 발송 과정에서 TLS 관련 오류 발생 시
// properties.put("mail.smtp.ssl.trust", "smtp.gmail.com"); // SSL 인증 신뢰 서버 주소 설정
// 3. 메일 서버 인증 정보를 관리하는 사용자 정의 클래스의 인스턴스 생성
Authenticator authenticator = new GoogleMailAuthenticator();
// 4. 자바 메일 전송을 수행하는 작업을 javax.mail.Session 객체 단위로 관리
Session mailSession = Session.getDefaultInstance(properties, authenticator);
// 5. 서버 정보와 인증 정보를 함께 관리할 javax.mail.internet.MimeMessage 객체 생성
Message message = new MimeMessage(mailSession);
// 6. 전송할 메일 정보 설정
// 1) 발신자 정보 생성
Address senderAddress = new InternetAddress(sender, "아이티윌");
// 2) 수신자 정보 생성
Address receiverAddress = new InternetAddress(receiver);
// 3) Message 객체를 통해 전송할 메일에 대한 내용 설정
// 3-1) 메일 헤더 정보 설정
message.setHeader("content-type", "text/html; charset=UTF-8");
// 3-2) 발신자 정보 설정
message.setFrom(senderAddress);
// 3-2) 수신자 정보 설정
message.addRecipient(RecipientType.TO, receiverAddress);
// 3-4) 메일 제목 설정
message.setSubject(title);
// 3-5) 메일 본문 설정
message.setContent("<h1>" + content + "</h1>", "text/html; charset=UTF-8");
// 3-6) 메일 전송 날짜 및 시각 설정
message.setSentDate(new Date());
// 7. 메일 전송
Transport.send(message);
// 메일 발송 후 처리(출력스트림으로 메세지 출력)
response.setContentType("text/html; charset=UTF-8");
PrintWriter out = response.getWriter();
out.println("<script>");
out.println("alert('메일 발송 성공!');");
out.println("</script>");
out.flush();
} catch (Exception e) {
e.printStackTrace();
// 메일 발송 실패 후 처리(출력스트림으로 메세지 출력)
response.setContentType("text/html; charset=UTF-8");
PrintWriter out = response.getWriter();
out.println("<script>");
out.println("alert('메일 발송 실패!');");
out.println("</script>");
out.flush();
}
}
}
--------------------------------코드 분석--------------------------------------
request.setCharacterEncoding("UTF-8");
String sender = request.getParameter("sender");
String receiver = request.getParameter("receiver");
String title = request.getParameter("title");
String content = request.getParameter("content");
- mail_form.jsp 페이지로부터 전달받은 폼 파라미터 가져와서 확인
Properties properties = System.getProperties();
- 1.시스템(현재 서버 = 톰캣)의 속성 정보(= 서버 정보)를 관리하는 객체를
java.util.Properties 객체로 리턴받기
properties.put("mail.smtp.host", "smtp.gmail.com"); // 구글(Gmail) SMTP 서버 주소
properties.put("mail.smtp.auth", "true"); // SMTP 서버 접근 시 인증 여부 설정
properties.put("mail.smtp.port", "587"); // Gmail 서버의 서비스 포트 설정(TLS)
// 메일 서버 인증 관련 추가 정보 설정(설정 내용에 따라 port 정보가 바뀜)
properties.put("mail.smtp.starttls.enable", "true"); // TLS 라는 인증 프로토콜 사용 여부 설정
properties.put("mail.smtp.ssl.protocols", "TLSv1.2"); // TLS 인증 프로토콜 버전 설정
// 만약, 메일 발송 과정에서 TLS 관련 오류 발생 시
// properties.put("mail.smtp.ssl.trust", "smtp.gmail.com"); // SSL 인증 신뢰 서버 주소 설정
- 2. Properties 객체를 활용하여 메일 전송에 필요한 기본 정보를 서버 정보에 추가
=> put() 메서드 활용
메일 전송에 사용할 메일 서버에 대한 정보 설정(구글, 네이버, 아웃룩 등)
Authenticator authenticator = new GoogleMailAuthenticator
- 3. 메일 서버 인증 정보를 관리하는 사용자 정의 클래스의 인스턴스 생성
=> javax.Mail.Authenticator 타입으로 업캐스팅하여 사용
Session mailSession = Session.getDefaultInstance(properties, authenticator);
- 4. 자바 메일 전송을 수행하는 작업을 javax.mail.Session 객체 단위로 관리하므로
Session 클래스의 getDefailtInstance() 메서드를 호출하여 Session 객체 리턴받기
=> 주의! 웹에서 사용하는 기본 세션 객체(HttpSession) 과 다르다!
=> 파라미터 : Properties 객체, Authenticator 객체
Message message = new MimeMessage(mailSession);
- 5. 서버 정보와 인증 정보를 함께 관리할 javax.mail.internet.MimeMessage 객체 생성
=> javax.mail.Message 타입으로 업캐스팅
=> 파라미터 : javax.mail.Session 객체
Address senderAddress = new InternetAddress(sender, "아이티윌");
- 6. 전송할 메일 정보 설정
1) 발신자 정보 생성
- InternetAddress 객체 생성(=> Address 타입 업캐스팅)
=> 파라미터 : 발신자 주소, 발신자 이름
=> 단, 사용 메일 서버(구글, 네이버 등)의 경우 스팸 정책으로 인해
기본적인 방법으로는 발신자 주소 변경 불가(기본 계정 주소 그대로 사용됨)
Address receiverAddress = new InternetAddress(receiver);
- 2) 수신자 정보 생성
- InternetAddress 객체 생성
=> 파라미터 : 수신자 주소
=> AddressException 처리 필요
3) Message 객체를 통해 전송할 메일에 대한 내용 설정
=> MessagingException 처리 필요
message.setHeader("content-type", "text/html; charset=UTF-8");
- 3-1) 메일 헤더 정보 설정
message.setFrom(senderAddress);
- 3-2) 발신자 정보 설정
message.addRecipient(RecipientType.TO, receiverAddress);
- 3-3) 수신자 정보 설정
=> 파라미터 : 수신 타입, 수신자 정보 객체
더 알면 좋은것
=> RecipientType.TO : 수신자에게 직접 전송(직접 받을 수신자 = 업무 담당자)
=> RecipientType.CC : 참조. Carbon Copy 의 약자. 직접적 수신자는 아니나 참조용으로 수신(= 업무 관계자)
=> RecipientType.BCC : 숨은참조, Blind CC 약자. 다른 사람들이 누가 참조하는지 알 수 없게 숨김 처리
message.setSubject(title);
- 3-4) 메일 제목 설정
message.setContent("<h1>" + content + "</h1>", "text/html; charset=UTF-8");
- 3-5) 메일 본문 설정
=> 파라미터 : 본문, 본문의 컨텐츠 타입
(만약, 파일 전송을 포함하려면 Multipart 타입 파라미터 객체 필요)
message.setSentDate(new Date());
- 3-6) 메일 전송 날짜 및 시각 설정
=> java.util.Date 객체 활용하여 현재 시스템 시각 정보 활용
Transport.send(message);
- 7. 메일 전송
javax.mail.Transport 클래스의 static 메서드 send() 호출
=> 파라미터 : 6번에서 생성한 Message 객체
메일 발송 후 처리(출력스트림으로 메세지 출력)
response.setContentType("text/html; charset=UTF-8");
PrintWriter out = response.getWriter();
out.println("<script>");
out.println("alert('메일 발송 성공!');");
out.println("</script>");
out.flush();
} catch (Exception e) {
e.printStackTrace();
메일 발송 실패 후 처리(출력스트림으로 메세지 출력)
response.setContentType("text/html; charset=UTF-8");
PrintWriter out = response.getWriter();
out.println("<script>");
out.println("alert('메일 발송 실패!');");
out.println("</script>");
out.flush();
}
이제 실행해보자
제출을 눌러보면
성공 알림창이 뜨고
구글 이메일을 가보면 잘 보내진걸 확인 할 수 있다
다음 시간에는 스프링으로 실습을 해보자.