이전에 AWS SES(Simple Email Service) Java 사용법을 통해 AWS의 SES를 Spring에서 적용시켜 보았다. 이번엔 SMTP 서버를 이용하여 메일을 전송해보려고 한다.
SES에서 SMTP settings
-> Create SMTP credentials
순서로 클릭한다. 그 후 SMTP credentials를 생성해준다.
그럼 다음과 같이 새로운 access-id와 secret-key를 발급받을 수 있다.
요청할 SMTP host와 port의 정보는 다음에 적혀있다.
해당 내용의 코드를 진행하기 위해서는 javax.mail의 의존성 추가가 필요합니다.
dependencies {
implementation 'org.springframework.boot:spring-boot-starter-mail:2.7.3'
}
public class SesServiceTest {
...
@Test
@DisplayName("java mail로 전송에 성공한다.")
void javaMailSend() throws UnsupportedEncodingException, MessagingException {
// Replace sender@example.com with your "From" address.
// This address must be verified.
final String FROM = "{보내는 email}";
final String FROMNAME = "{보내는 email 별명}";
// Replace recipient@example.com with a "To" address. If your account
// is still in the sandbox, this address must be verified.
final String TO = "{받을 email}";
// Replace smtp_username with your Amazon SES SMTP user name.
final String SMTP_USERNAME = "{SMTP user name}";
// Replace smtp_password with your Amazon SES SMTP password.
final String SMTP_PASSWORD = "{SMTP password}";
// The name of the Configuration Set to use for this message.
// If you comment out or remove this variable, you will also need to
// comment out or remove the header below.
final String CONFIGSET = "ConfigSet";
// Amazon SES SMTP host name. This example uses the US West (Oregon) region.
// See https://docs.aws.amazon.com/ses/latest/DeveloperGuide/regions.html#region-endpoints
// for more information.AP_NORTHEAST_2
final String HOST = "email-smtp.ap-northeast-2.amazonaws.com";
// The port you will connect to on the Amazon SES SMTP endpoint.
final int PORT = 587;
final String SUBJECT = "Amazon SES test (SMTP interface accessed using Java)";
final String BODY = String.join(
System.getProperty("line.separator"),
"<h1>Amazon SES SMTP Email Test</h1>",
"<p>This email was sent with Amazon SES using the ",
"<a href='https://github.com/javaee/javamail'>Javamail Package</a>",
" for <a href='https://www.java.com'>Java</a>."
);
// Create a Properties object to contain connection configuration information.
Properties props = System.getProperties();
props.put("mail.transport.protocol", "smtp");
props.put("mail.smtp.port", PORT);
props.put("mail.smtp.starttls.enable", "true");
props.put("mail.smtp.auth", "true");
// Create a Session object to represent a mail session with the specified properties.
Session session = Session.getDefaultInstance(props);
// Create a message with the specified information.
MimeMessage msg = new MimeMessage(session);
msg.setFrom(new InternetAddress(FROM,FROMNAME));
msg.setRecipient(Message.RecipientType.TO, new InternetAddress(TO));
msg.setSubject(SUBJECT, StandardCharsets.UTF_8.name());
msg.setText(BODY, StandardCharsets.UTF_8.name(), "html");
// Add a configuration set header. Comment or delete the
// next line if you are not using a configuration set
// msg.setHeader("X-SES-CONFIGURATION-SET", CONFIGSET);
// Create a transport.
Transport transport = session.getTransport();
// Send the message.
try
{
System.out.println("Sending...");
// Connect to Amazon SES using the SMTP username and password you specified above.
transport.connect(HOST, SMTP_USERNAME, SMTP_PASSWORD);
// Send the email.
transport.sendMessage(msg, msg.getAllRecipients());
System.out.println("Email sent!");
}
catch (Exception ex) {
System.out.println("The email was not sent.");
System.out.println("Error message: " + ex.getMessage());
fail();
}
finally
{
// Close and terminate the connection.
transport.close();
}
}
}
AWS 공식 홈페이지의 코드를 참고하여 테스트 코드를 작성하였다. 이렇게 만들어서 코드를 실행시키면
정상 실행되었고
html도 정상적으로 적용되었고 보낸 사람의 별명도 정상적으로 적용되어진 것을 확인할 수 있다.
테스트 코드로는 작성해서 테스트를 해봤으니 이제 공통적으로 사용할 코드를 분리해보자.
aws:
ses:
host: {smtp region}
port: {smtp port}
access-id: {smtp username}
secret-key: {smtp password}
@Slf4j
@RequiredArgsConstructor
public class Sender {
private final Environment env;
public boolean send(String from, String fromName, String to, String subject, String content){
log.info("Sender send() start ...");
String host = env.getProperty("aws.ses.host");
String port = env.getProperty("aws.ses.port");
String userName = env.getProperty("aws.ses.access-id");
String password = env.getProperty("aws.ses.secret-key");
Properties props = System.getProperties();
props.put("mail.transport.protocol", "smtp");
props.put("mail.smtp.port", Integer.parseInt(port));
props.put("mail.smtp.starttls.enable", "true");
props.put("mail.smtp.auth", "true");
Session session = Session.getDefaultInstance(props);
MimeMessage msg = new MimeMessage(session);
try {
msg.setFrom(new InternetAddress(from, fromName));
msg.setRecipient(Message.RecipientType.TO, new InternetAddress(to));
msg.setSubject(subject, StandardCharsets.UTF_8.name());
msg.setText(content, StandardCharsets.UTF_8.name(), "html");
//메일 전송
log.info("mail send start ...");
Transport transport = session.getTransport();
transport.connect(host, userName, password);
transport.sendMessage(msg, msg.getAllRecipients());
log.info("mail send complete ...");
} catch (UnsupportedEncodingException e) {
// InternetAddress 만들 때 Exception
e.printStackTrace();
return false;
} catch (MessagingException e) {
// setForm 할 때 Exception
e.printStackTrace();
return false;
}
return true;
}
}
다음과 같이 작성하고
@SpringBootTest
public class SesServiceTest {
@Autowired
private Environment env;
@Test
@DisplayName("SMTP 메일 전송에 성공한다.")
void smtpSend(){
// given
Sender sender = new Sender(env);
// when
boolean result =
sender.send("{보낼 메일}", "{보낼 메일 별명}", "{받을 메일 List}", "{메일 제목}", "{메일 내용}");
//then
assertTrue(result);
}
}
테스트를 진행하면 정상적으로 메일을 받아볼 수 있다!