From 08352358ec00c39a2f140dc1fe37c1982b444f35 Mon Sep 17 00:00:00 2001 From: Jong1 <44349716+donsonioc2010@users.noreply.github.com> Date: Tue, 19 Sep 2023 12:50:09 +0900 Subject: [PATCH] =?UTF-8?q?[feat]=20=EB=A9=94=EC=9D=BC=20=EB=B0=9C?= =?UTF-8?q?=EC=86=A1=EA=B8=B0=EB=8A=A5=20=EA=B5=AC=ED=98=84=20=EC=99=84?= =?UTF-8?q?=EB=A3=8C=20(#33)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * chore : 메일 의존성 추가 * docs : Project Site Link 추가 * feat : 메일 기능 추가 * feat : 메일 기능 사용법 SampleCase 추가 * feat : 메일 위치 상수 클래스 생성 --- .../server/api/mail/MailPathConstants.java | 5 ++ .../server/api/mail/TestMailController.java | 39 ++++++++++ .../main/resources/templates/mail/sample.html | 16 +++++ Common/build.gradle | 3 + .../common/exception/GlobalException.java | 11 +-- .../exception/IllegalArgumentException.java | 11 +++ .../common/exception/MailSendException.java | 11 +++ .../server/common/mail/SendMailUtil.java | 71 +++++++++++++++++++ .../src/main/resources/application-common.yml | 12 ++++ README.md | 6 +- 10 files changed, 178 insertions(+), 7 deletions(-) create mode 100644 Api/src/main/java/picasso/server/api/mail/MailPathConstants.java create mode 100644 Api/src/main/java/picasso/server/api/mail/TestMailController.java create mode 100644 Api/src/main/resources/templates/mail/sample.html create mode 100644 Common/src/main/java/picasso/server/common/exception/IllegalArgumentException.java create mode 100644 Common/src/main/java/picasso/server/common/exception/MailSendException.java create mode 100644 Common/src/main/java/picasso/server/common/mail/SendMailUtil.java diff --git a/Api/src/main/java/picasso/server/api/mail/MailPathConstants.java b/Api/src/main/java/picasso/server/api/mail/MailPathConstants.java new file mode 100644 index 00000000..1d106205 --- /dev/null +++ b/Api/src/main/java/picasso/server/api/mail/MailPathConstants.java @@ -0,0 +1,5 @@ +package picasso.server.api.mail; + +public class MailPathConstants { + public static String SAMPLE_MAIL = "mail/sample"; +} diff --git a/Api/src/main/java/picasso/server/api/mail/TestMailController.java b/Api/src/main/java/picasso/server/api/mail/TestMailController.java new file mode 100644 index 00000000..0134adc1 --- /dev/null +++ b/Api/src/main/java/picasso/server/api/mail/TestMailController.java @@ -0,0 +1,39 @@ +package picasso.server.api.mail; + +import lombok.RequiredArgsConstructor; +import lombok.extern.slf4j.Slf4j; +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RequestParam; +import org.springframework.web.bind.annotation.RestController; +import picasso.server.common.mail.SendMailUtil; + +import java.util.HashMap; + +/* + * TODO : 해당 컨트롤러 사용법 안내를 위한 TestController로 추후 삭제가 필요합니다. + */ +@Slf4j +@RequestMapping("/mail") +@RequiredArgsConstructor +@RestController +public class TestMailController { + private final SendMailUtil sendMailUtil; + + /** + * @param mail 메일을 파라미터로 필요 id@mailHost + * @return + */ + @GetMapping("/test") + public boolean testMail(@RequestParam("mail") String mail) { + return sendMailUtil.sendMail( + mail, + "테스트메일입니다.", + MailPathConstants.SAMPLE_MAIL, + new HashMap<>() {{ + put("a", "A변수 데이터 입니다."); + put("b", "B변수 데이터 입니다."); + }}); + } + +} diff --git a/Api/src/main/resources/templates/mail/sample.html b/Api/src/main/resources/templates/mail/sample.html new file mode 100644 index 00000000..75ab5604 --- /dev/null +++ b/Api/src/main/resources/templates/mail/sample.html @@ -0,0 +1,16 @@ + + + +
+

테스트 SampleMail 입니다.

+

+
+ +
+
+ + \ No newline at end of file diff --git a/Common/build.gradle b/Common/build.gradle index 9e8e670a..5d73b364 100644 --- a/Common/build.gradle +++ b/Common/build.gradle @@ -7,6 +7,9 @@ dependencies { api 'org.springframework.boot:spring-boot-starter-aop' api 'org.springframework.boot:spring-boot-starter-validation' + // Mail + api 'org.springframework.boot:spring-boot-starter-mail' + //File api 'commons-io:commons-io:2.13.0' diff --git a/Common/src/main/java/picasso/server/common/exception/GlobalException.java b/Common/src/main/java/picasso/server/common/exception/GlobalException.java index a407be1c..bc87e739 100644 --- a/Common/src/main/java/picasso/server/common/exception/GlobalException.java +++ b/Common/src/main/java/picasso/server/common/exception/GlobalException.java @@ -1,12 +1,12 @@ package picasso.server.common.exception; -import static org.springframework.http.HttpStatus.BAD_REQUEST; -import static org.springframework.http.HttpStatus.INTERNAL_SERVER_ERROR; - import lombok.AllArgsConstructor; import lombok.Getter; import picasso.server.common.dto.ErrorDetail; +import static org.springframework.http.HttpStatus.BAD_REQUEST; +import static org.springframework.http.HttpStatus.INTERNAL_SERVER_ERROR; + @Getter @AllArgsConstructor public enum GlobalException implements BaseErrorCode { @@ -16,8 +16,9 @@ public enum GlobalException implements BaseErrorCode { DATE_FORMAT_ERROR(BAD_REQUEST.value(), "날짜 형식을 확인해주세요."), FILE_UPLOAD_ERROR(INTERNAL_SERVER_ERROR.value(), "파일 업로드 중 오류가 발생하였습니다"), FILE_DELETE_ERROR(INTERNAL_SERVER_ERROR.value(), "파일 삭제 중 오류가 발생하였습니다"), - FILE_IO_ERROR(INTERNAL_SERVER_ERROR.value(), "파일 변환 중 오류가 발생하였습니다") - ; + FILE_IO_ERROR(INTERNAL_SERVER_ERROR.value(), "파일 변환 중 오류가 발생하였습니다"), + ILLEGAL_ARGUMENT_ERROR(BAD_REQUEST.value(), "인자 값 문제로 인한 오류가 발생하였습니다"), + MAIL_SEND_ERROR(INTERNAL_SERVER_ERROR.value(), "메일 발송중 오류가 발생하였습니다"); private final Integer statusCode; private final String reason; diff --git a/Common/src/main/java/picasso/server/common/exception/IllegalArgumentException.java b/Common/src/main/java/picasso/server/common/exception/IllegalArgumentException.java new file mode 100644 index 00000000..c3037d50 --- /dev/null +++ b/Common/src/main/java/picasso/server/common/exception/IllegalArgumentException.java @@ -0,0 +1,11 @@ +package picasso.server.common.exception; + +import static picasso.server.common.exception.GlobalException.ILLEGAL_ARGUMENT_ERROR; + +public class IllegalArgumentException extends BaseException { + public static final BaseException EXCEPTION = new IllegalArgumentException(); + + public IllegalArgumentException() { + super(ILLEGAL_ARGUMENT_ERROR); + } +} diff --git a/Common/src/main/java/picasso/server/common/exception/MailSendException.java b/Common/src/main/java/picasso/server/common/exception/MailSendException.java new file mode 100644 index 00000000..2cc9c2ef --- /dev/null +++ b/Common/src/main/java/picasso/server/common/exception/MailSendException.java @@ -0,0 +1,11 @@ +package picasso.server.common.exception; + +import static picasso.server.common.exception.GlobalException.MAIL_SEND_ERROR; + +public class MailSendException extends BaseException { + public static final MailSendException EXCEPTION = new MailSendException(); + + public MailSendException() { + super(MAIL_SEND_ERROR); + } +} diff --git a/Common/src/main/java/picasso/server/common/mail/SendMailUtil.java b/Common/src/main/java/picasso/server/common/mail/SendMailUtil.java new file mode 100644 index 00000000..4d97aa74 --- /dev/null +++ b/Common/src/main/java/picasso/server/common/mail/SendMailUtil.java @@ -0,0 +1,71 @@ +package picasso.server.common.mail; + +import jakarta.mail.Message; +import jakarta.mail.MessagingException; +import jakarta.mail.internet.MimeMessage; +import lombok.RequiredArgsConstructor; +import lombok.extern.slf4j.Slf4j; +import org.springframework.mail.javamail.JavaMailSender; +import org.springframework.stereotype.Component; +import org.thymeleaf.context.Context; +import org.thymeleaf.spring6.SpringTemplateEngine; +import picasso.server.common.exception.IllegalArgumentException; +import picasso.server.common.exception.MailSendException; + +import java.util.Map; + +import static org.apache.commons.codec.CharEncoding.UTF_8; + +@Slf4j +@Component +@RequiredArgsConstructor +public class SendMailUtil { + private final JavaMailSender javaMailSender; + private final SpringTemplateEngine templateEngine; + + + /** + * Key는 현재 Mail에 사용중인 변수를, Value는 해당 메일 페이지에 들어갈 값을 입력하면 됩니다. + * + * @param toUser 발송자 메일 + * @param title 메일 제목 + * @param pagePath ThymeLeaf(HTML)파일 경로 + * @param content ThymeLeaf에 들어갈 변수 Map (Not Null!!!) + * @return + */ + public boolean sendMail(String toUser, String title, String pagePath, Map content) { + try { + parameterValidate(toUser, title, content); + MimeMessage message = javaMailSender.createMimeMessage(); + message.addRecipients(Message.RecipientType.TO, toUser); + message.setSubject(title, UTF_8); + message.setText(getContent(pagePath, content), UTF_8, "html"); + javaMailSender.send(message); + log.info("[SendMail Success] ToUser >>> {}, Title >>> {}, PagePath >>> {}", toUser, title, pagePath); + return true; + } catch (MessagingException e) { + log.error("[SendMail Failed] Exception Reason >>> MessageException, ToUser >>> {}, Title >>> {}, PagePath >>> {}", toUser, title, pagePath); + throw MailSendException.EXCEPTION; + } catch (Exception e) { + log.error("[SendMail Failed] Exception Reason >>> {}, ToUser >>> {}, Title >>> {}, PagePath >>> {}", e.getClass(), toUser, title, pagePath); + throw MailSendException.EXCEPTION; + } + } + + + //Valid, NotNull를 쓸까했는데... 안먹는걸로 기억이나서.. + private void parameterValidate(String toUser, String title, Map content) { + if (toUser == null || title == null || content == null || + title.isEmpty() || toUser.isEmpty()) { + throw IllegalArgumentException.EXCEPTION; + } + } + + // html파일에서 메일내용을 가져옴 + private String getContent(String pagePath, Map content) { + Context context = new Context(); + content.forEach(context::setVariable); + return templateEngine.process(pagePath, context); + } + +} diff --git a/Common/src/main/resources/application-common.yml b/Common/src/main/resources/application-common.yml index 761cc112..08c204eb 100644 --- a/Common/src/main/resources/application-common.yml +++ b/Common/src/main/resources/application-common.yml @@ -4,6 +4,18 @@ naver: region-name: kr-standard bucket-name: picasso-bucket + +spring: + mail: + host: smtp.gmail.com + port: 587 + properties: + mail: + smtp: + auth: true + starttls: + enable: true + --- spring: config: diff --git a/README.md b/README.md index 1efd92b7..db908d22 100644 --- a/README.md +++ b/README.md @@ -1,5 +1,7 @@ -# Picasso -[![Hits](https://hits.seeyoufarm.com/api/count/incr/badge.svg?url=https%3A%2F%2Fgithub.com%2Fdonsonioc2010%2Fpicasso&count_bg=%2379C83D&title_bg=%23555555&icon=&icon_color=%23E7E7E7&title=hits&edge_flat=false)](https://hits.seeyoufarm.com) +# Picasso +[홈페이지 링크](http://picasso.jong1.com/) [![Hits](https://hits.seeyoufarm.com/api/count/incr/badge.svg?url=https%3A%2F%2Fgithub.com%2Fdonsonioc2010%2Fpicasso&count_bg=%2379C83D&title_bg=%23555555&icon=&icon_color=%23E7E7E7&title=hits&edge_flat=false)](https://hits.seeyoufarm.com) + +--- ## 주제 > [!NOTE] > 미술품 경매 사이트