From 95a14184813d9447b2a99252ba8d7fdb990332d7 Mon Sep 17 00:00:00 2001 From: Florian THIERRY Date: Mon, 17 May 2021 22:37:08 +0200 Subject: [PATCH] Add validator and service to refactor. --- .../controller/EmailController.java | 6 +- .../exception/BadRequestException.java | 15 +++++ .../exception/BusinessException.java | 26 ++++++++ .../services/validator/UserValidator.java | 21 +++++++ .../torefactor/MonolithController.java | 61 +++++++++++++++++++ src/main/resources/application.yml | 6 ++ 6 files changed, 134 insertions(+), 1 deletion(-) create mode 100644 src/main/java/fr/ippon/example/intellijfeatures/exception/BadRequestException.java create mode 100644 src/main/java/fr/ippon/example/intellijfeatures/exception/BusinessException.java create mode 100644 src/main/java/fr/ippon/example/intellijfeatures/services/validator/UserValidator.java create mode 100644 src/main/java/fr/ippon/example/intellijfeatures/torefactor/MonolithController.java diff --git a/src/main/java/fr/ippon/example/intellijfeatures/controller/EmailController.java b/src/main/java/fr/ippon/example/intellijfeatures/controller/EmailController.java index e590013..8f37101 100644 --- a/src/main/java/fr/ippon/example/intellijfeatures/controller/EmailController.java +++ b/src/main/java/fr/ippon/example/intellijfeatures/controller/EmailController.java @@ -2,6 +2,7 @@ package fr.ippon.example.intellijfeatures.controller; import fr.ippon.example.intellijfeatures.model.User; import fr.ippon.example.intellijfeatures.services.mail.EmailService; +import fr.ippon.example.intellijfeatures.services.validator.UserValidator; import org.springframework.web.bind.annotation.*; import static org.springframework.http.HttpStatus.NO_CONTENT; @@ -10,14 +11,17 @@ import static org.springframework.http.HttpStatus.NO_CONTENT; @RequestMapping("/api/mails") public class EmailController { private final EmailService emailService; + private final UserValidator userValidator; - public EmailController(EmailService emailService) { + public EmailController(EmailService emailService, UserValidator userValidator) { this.emailService = emailService; + this.userValidator = userValidator; } @PostMapping("/send") @ResponseStatus(NO_CONTENT) public void sendMail(@RequestBody User user) { + userValidator.check(user); emailService.sendMail(user); } } diff --git a/src/main/java/fr/ippon/example/intellijfeatures/exception/BadRequestException.java b/src/main/java/fr/ippon/example/intellijfeatures/exception/BadRequestException.java new file mode 100644 index 0000000..3f16f90 --- /dev/null +++ b/src/main/java/fr/ippon/example/intellijfeatures/exception/BadRequestException.java @@ -0,0 +1,15 @@ +package fr.ippon.example.intellijfeatures.exception; + +import org.springframework.http.HttpStatus; +import org.springframework.web.bind.annotation.ResponseStatus; + +@ResponseStatus(value = HttpStatus.BAD_REQUEST) +public class BadRequestException extends BusinessException { + public BadRequestException(String message) { + super(message); + } + + public BadRequestException(String message, Throwable cause) { + super(message, cause); + } +} diff --git a/src/main/java/fr/ippon/example/intellijfeatures/exception/BusinessException.java b/src/main/java/fr/ippon/example/intellijfeatures/exception/BusinessException.java new file mode 100644 index 0000000..1c0a23b --- /dev/null +++ b/src/main/java/fr/ippon/example/intellijfeatures/exception/BusinessException.java @@ -0,0 +1,26 @@ +package fr.ippon.example.intellijfeatures.exception; + +/** + * Business exception. + */ +public class BusinessException extends RuntimeException { + + public BusinessException() {} + + /** + * Constructs an exception with a message. + * @param message The description of the error met. + */ + public BusinessException(final String message) { + super(message); + } + + /** + * Constructs an exception with a message and a code. + * @param message The description of the error met. + * @param cause The cause of the exception. + */ + public BusinessException(final String message, final Throwable cause) { + super(message, cause); + } +} diff --git a/src/main/java/fr/ippon/example/intellijfeatures/services/validator/UserValidator.java b/src/main/java/fr/ippon/example/intellijfeatures/services/validator/UserValidator.java new file mode 100644 index 0000000..8d405c5 --- /dev/null +++ b/src/main/java/fr/ippon/example/intellijfeatures/services/validator/UserValidator.java @@ -0,0 +1,21 @@ +package fr.ippon.example.intellijfeatures.services.validator; + +import fr.ippon.example.intellijfeatures.exception.BadRequestException; +import fr.ippon.example.intellijfeatures.model.User; +import org.springframework.stereotype.Component; +import org.springframework.util.ObjectUtils; + +import java.util.regex.Pattern; + +@Component +public class UserValidator { + public void check(User user) { + if (user.getName() == null || ObjectUtils.isEmpty(user.getName())) { + throw new BadRequestException("User name is required."); + } + + if (user.getEmail() == null || !Pattern.matches("\\w+@\\w+\\.\\w+", user.getEmail())) { + throw new BadRequestException("User email is required and should be a valid email."); + } + } +} diff --git a/src/main/java/fr/ippon/example/intellijfeatures/torefactor/MonolithController.java b/src/main/java/fr/ippon/example/intellijfeatures/torefactor/MonolithController.java new file mode 100644 index 0000000..4708e05 --- /dev/null +++ b/src/main/java/fr/ippon/example/intellijfeatures/torefactor/MonolithController.java @@ -0,0 +1,61 @@ +package fr.ippon.example.intellijfeatures.torefactor; + +import com.mitchellbosecke.pebble.PebbleEngine; +import fr.ippon.example.intellijfeatures.exception.BadRequestException; +import fr.ippon.example.intellijfeatures.model.User; +import org.springframework.http.HttpStatus; +import org.springframework.mail.javamail.JavaMailSender; +import org.springframework.mail.javamail.MimeMessageHelper; +import org.springframework.util.ObjectUtils; +import org.springframework.util.StringUtils; +import org.springframework.web.bind.annotation.*; + +import javax.mail.MessagingException; +import javax.mail.internet.MimeMessage; +import java.io.IOException; +import java.io.StringWriter; +import java.io.Writer; +import java.util.Map; +import java.util.regex.Pattern; + +@RestController +@RequestMapping("/api/mail2") +public class MonolithController { + private final JavaMailSender javaMailSender; + + public MonolithController(JavaMailSender javaMailSender) { + this.javaMailSender = javaMailSender; + } + + @PostMapping("/send") + @ResponseStatus(HttpStatus.NO_CONTENT) + public void sendMail(@RequestBody User user) throws IOException, MessagingException { + if (user.getName() == null || ObjectUtils.isEmpty(user.getName())) { + throw new BadRequestException("User name is required."); + } + + if (user.getEmail() == null || !Pattern.matches("\\w+@\\w+\\.\\w+", user.getEmail())) { + throw new BadRequestException("User email is required and should be a valid email."); + } + + PebbleEngine pebbleEngine = new PebbleEngine.Builder().build(); + + Writer writer = new StringWriter(); + pebbleEngine.getTemplate("templates/mail/user-mail.html") + .evaluate(writer, Map.of("user", user)); + String htmlContent = writer.toString(); + + Writer writer2 = new StringWriter(); + pebbleEngine.getTemplate("templates/mail/user-mail.txt") + .evaluate(writer2, Map.of("user", user)); + String textContent = writer2.toString(); + + MimeMessage mimeMessage = javaMailSender.createMimeMessage(); + + MimeMessageHelper helper = new MimeMessageHelper(mimeMessage, true); + helper.setTo(user.getEmail()); + helper.setSubject("Hello"); + helper.setText(textContent, htmlContent); + javaMailSender.send(mimeMessage); + } +} diff --git a/src/main/resources/application.yml b/src/main/resources/application.yml index c496fff..8c1e807 100644 --- a/src/main/resources/application.yml +++ b/src/main/resources/application.yml @@ -1,3 +1,9 @@ +server: + error: + whitelabel: + enabled: false # Disable html error responses. + include-stacktrace: never + spring: mail: host: localhost