계속 인프라 관련 글만 올리다가
오랜만에 개발관련 글을 올려본다.
일반적으로 서버에 문제가 생기거나,
api 쪽에 문제가 발생하였을 경우에 SMTP를 통해서 outlook으로
메일을 전송하여 장애대응을 할 수 있게 해준다.
실제 운영환경에서는 훨씬 더 복잡한 로직이 있지만,
이 글에서는 SMTP 사용에만 포커스에 두고 설명할 것이다.
Spring framework를 기반으로 구성해 보겠다.
일단 아래와 같이 dependency를 pom.xml 에 추가해 주자.
<dependency>
<groupId>com.sun.mail</groupId>
<artifactId>javax.mail</artifactId>
<version>1.6.2</version>
</dependency>
테스트는 구글 계정을 통해 진행할 것이다.
일단 구글에 로그인을 해주고 계정설정탭으로 들어가 준다.
아래의 그림과 같이 보안탭으로 이동해 준다.
아래와 같은 탭에서 앱 비밀번호 쪽을 눌러준다.
이미 하나의 앱 비밀번호를 생성해놔서 현재 비밀번호 1개라고 보인다.
한 번도 앱 비밀번호를 설정한 적이 없는 경우에는 2단계 인증도 수행해야 했던 걸로 기억한다.
(2단계 인증 등록하는 방법은 어렵지 않으니 진행하면 된다.)
앱 비밀번호 탭을 눌러서 페이지가 이동되었다면 아래와 같은 모습의 페이지를 보게 될 것이다.
select box에서 해당되는 환경을 선택해주고 생성 버튼을 클릭해 준다.
앱 비밀번호를 생성하면 아래와 같이 비밀번호가 보인다.
해당 비밀번호는 SMTP를 위해 사용될 비밀번호 이므로
기억하거나 기록해놓는 것을 권장한다.
해당 작업을 모두 진행하였다면
다시 테스트 코드로 넘어와준다.
MessageSender Class를 생성해 준다.
import java.util.Properties;
import javax.mail.Message;
import javax.mail.PasswordAuthentication;
import javax.mail.Session;
import javax.mail.Transport;
import javax.mail.internet.InternetAddress;
import javax.mail.internet.MimeMessage;
/**
*
* @author sinseunghwan
*
*/
public class MessageSender {
private String user;
private String pass;
public MessageSender() {}
public MessageSender(String user, String pass) {
this.user = user;
this.pass = pass;
}
/**
* Send a message to one person in text format
* @param addresse
* @param subject
* @param contents
* @return
* @throws Exception
*/
public void sendTextMessage(String addresse, String subject, String contents) throws Exception {
// Setting SMTP Server Information
Properties prop = new Properties();
prop.put("mail.smtp.host", "smtp.gmail.com");
prop.put("mail.smtp.port", 465);
prop.put("mail.smtp.auth", "true");
prop.put("mail.smtp.ssl.enable", "true");
prop.put("mail.smtp.ssl.trust", "smtp.gmail.com");
Session session = Session.getDefaultInstance(prop, new javax.mail.Authenticator() {
protected PasswordAuthentication getPasswordAuthentication() {
return new PasswordAuthentication(user, pass);
}
});
MimeMessage message = new MimeMessage(session);
message.setFrom(new InternetAddress(user));
// 수신인 지정
message.addRecipient(Message.RecipientType.TO, new InternetAddress(addresse));
// 이메일 제목
message.setSubject(subject);
// 이메일 내용
message.setText(contents);
// 메일 보내주기
Transport.send(message);
}
}
해당 MessageSender Class의 기능이 정상적으로 작동하는지
확인해주기 위해서 컨트롤러 하나를 생성해 준다.
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import com.test.comutils.MessageSender;
@Controller
public class MessageController {
@RequestMapping(value = "/smtpTesting.action", method = { RequestMethod.GET , RequestMethod.POST})
public String testMain(HttpServletRequest request, HttpServletResponse response, MessageSender ms) {
try {
ms = new MessageSender("{구글 아이디}","{구글 앱 비밀번호}");
ms.sendTextMessage("{수신자 이메일}", "test", "Harimao");
return "";
} catch(Exception e) {
e.printStackTrace();
return "";
}
}
}
위의 프로젝트를 컴파일시킨 뒤에 서버를 실행해 주면
아래와 같이 메시지가 정상적으로 보내진 것을 알 수 있다.
아래와 같이 코드를 추가해 주면, 한 명이 아닌 여러 명에게도 이메일을 보내줄 수 있다.
import java.util.List;
import java.util.Properties;
import javax.mail.Message;
import javax.mail.PasswordAuthentication;
import javax.mail.Session;
import javax.mail.Transport;
import javax.mail.internet.InternetAddress;
import javax.mail.internet.MimeMessage;
/**
*
* @author sinseunghwan
*
*/
public class MessageSender {
private String user;
private String pass;
private MimeMessage message;
public MessageSender() {}
public MessageSender(String user, String pass) {
this.user = user;
this.pass = pass;
// Setting SMTP Server Information
Properties prop = new Properties();
prop.put("mail.smtp.host", "smtp.gmail.com");
prop.put("mail.smtp.port", 465);
prop.put("mail.smtp.auth", "true");
prop.put("mail.smtp.ssl.enable", "true");
prop.put("mail.smtp.ssl.trust", "smtp.gmail.com");
Session session = Session.getDefaultInstance(prop, new javax.mail.Authenticator() {
protected PasswordAuthentication getPasswordAuthentication() {
return new PasswordAuthentication(user, pass);
}
});
this.message = new MimeMessage(session);
}
/**
* Send a message to one person in text format
* @param addresse
* @param subject
* @param contents
* @return
* @throws Exception
*/
public void sendTextMessage(String addresse, String subject, String contents) throws Exception {
message.setFrom(new InternetAddress(user));
// Confirm Recipient
message.addRecipient(Message.RecipientType.TO, new InternetAddress(addresse));
// Subject
message.setSubject(subject);
// Contents
message.setText(contents);
// Send mail
Transport.send(message);
}
/**
* Sending mail to multiple people.
* @param addresse
* @param subject
* @param contents
* @throws Exception
*/
public void sendTextMessages(List<String> addresse, String subject, String contents) throws Exception {
message.setFrom(new InternetAddress(user));
InternetAddress[] toAddr = new InternetAddress[addresse.size()];
for (int i = 0; i < toAddr.length; i++) {
toAddr[i] = new InternetAddress(addresse.get(i));
}
// Confirm Recipient
message.setRecipients(Message.RecipientType.TO, toAddr);
// Subject
message.setSubject(subject);
// Contents
message.setText(contents);
// Send mail
Transport.send(message);
}
}
import java.util.ArrayList;
import java.util.List;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import com.test.comutils.MessageSender;
@Controller
public class MessageController {
@RequestMapping(value = "/smtpTesting.action", method = { RequestMethod.GET , RequestMethod.POST})
public String testMain(HttpServletRequest request, HttpServletResponse response, MessageSender ms) {
try {
ms = new MessageSender("{구글 아이디}","{구글 앱 비밀번호}");
List<String> userList = new ArrayList<String>();
userList.add("{수신자1 이메일}");
userList.add("{수신자2 이메일}");
ms.sendTextMessages(userList, "test2", "test2");
return "";
} catch(Exception e) {
e.printStackTrace();
return "";
}
}
}
또한, 아래의 코드를 추가해 준다면,
Text 문자뿐만 아니라 HTML 도 메일로 보내줄 수 있다.
/**
* Send a message to multiple people in html format
* @param addresse
* @param subject
* @param contents
* @throws Exception
*/
public void sendHtmlMessages(List<String> addresse, String subject, String contents) throws Exception {
message.setFrom(new InternetAddress(user));
InternetAddress[] toAddr = new InternetAddress[addresse.size()];
for (int i = 0; i < toAddr.length; i++) {
toAddr[i] = new InternetAddress(addresse.get(i));
}
// Confirm Recipient
message.setRecipients(Message.RecipientType.TO, toAddr);
// Subject
message.setSubject(subject);
//HTML Text
message.setContent(contents,"text/html; charset=utf-8");
// Send mail
Transport.send(message);
}
import java.io.StringWriter;
import java.util.ArrayList;
import java.util.List;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import com.test.comutils.MessageSender;
@Controller
public class MessageController {
@RequestMapping(value = "/smtpTesting.action", method = { RequestMethod.GET , RequestMethod.POST})
public String testMain(HttpServletRequest request, HttpServletResponse response, MessageSender ms) {
try {
ms = new MessageSender("{구글 아이디}","{구글 앱 비밀번호}");
List<String> userList = new ArrayList<String>();
userList.add("{수신자1 이메일}");
userList.add("{수신자2 이메일}");
// Test HTML code
StringWriter errors = new StringWriter();
errors.append("<table border='1' style='width:1200px;'>");
errors.append("<th colspan = '2' style='color:red; font-size: 2em; font-weight: bolder;'>Error Occurred In SYJ_Mall</th>");
errors.append("<tr><td>machine ip</td><td>Date of occurrence</td></tr>");
errors.append("<tr><td>");
errors.append("0.0.0.0");
errors.append("</td><td>");
errors.append("2023-01-08 00:00:00");
errors.append("</td></tr>");
errors.append("<tr><td colspan='2' style='color: red; font-size: 1.3em; font-weight: bolder; text-align: center;'>Error Log</td></tr>");
errors.append("<tr><td colspan='2'>");
errors.append("ERROR contents");
errors.append("</td></tr></table>");
String errorsMsg = errors.toString();
errorsMsg = errorsMsg.replaceAll("\\)", ")<br>");
errorsMsg = errorsMsg.replaceAll("\\###", "<br>###");
ms.sendHtmlMessages(userList, "test html", errorsMsg);
return "";
} catch(Exception e) {
e.printStackTrace();
return "";
}
}
}
'개발 & 구현' 카테고리의 다른 글
[c++] Elasticsearch Cluster metric 알람 구현 - 최적화 (0) | 2023.09.19 |
---|---|
[c++] Elasticsearch Cluster metric 알람 구현 (2) | 2023.09.18 |
[Python] Telegram 응답 받기 (0) | 2023.05.03 |
[Python] Telegram 메시지 보내주기 (0) | 2023.05.02 |
QR코드 로그인 구현 (1) | 2022.05.13 |