Código específico del medio ambiente en el método de correo de @async con la primavera -- java campo con email campo con spring camp codereview Relacionados El problema

Environment-specific code in @Async mail method with Spring


1
vote

problema

Español

Tengo un resorte @Service para enviar los correos electrónicos de forma asíncrona. La parte que parece estar un poco fuera para mí es un código que es específico para nuestro entorno de control de calidad. Queremos enviar y recibir todos los correos electrónicos a través de una cuenta de correo electrónico de prueba para que no afecte a los usuarios en vivo si trabajamos con datos reales importados a QA. Verifico el entorno y algunas configuraciones en archivos .properties y ajusta el correo electrónico saliente en consecuencia.

¿Hay una mejor manera de manejar esto?

  @Async public void send(String email, String subject, String body) {      if (email == null) {         log.error("Not sending; null input: email");         return;     }     try {         MimeMessage message = this.mailSender.createMimeMessage();         MimeMessageHelper helper = new MimeMessageHelper(message);         helper.setFrom(mailSender.getUsername(), getFrom());         helper.setReplyTo(mailSender.getUsername());         helper.setSubject(subject);          //HERE IS THE PART THAT'S IFFY:          if ("QA".equalsIgnoreCase(EmailManager.getEnvironmentName())) {             if (isTestMode()) {                 if (!email.equals(getTestEmailAddress())) {                     helper.setTo(getTestEmailAddress());                     body += "<br/>This email was originally intended for " + email +                             " but was redirected to " + getTestEmailAddress() + " for testing.";                     helper.setText(body, true); //HTML on                 }             }         }         else {             helper.setTo(email);             helper.setText(body, true); //HTML on         }          if (message == null) {             log.error("Email message to send is null.  Email={}, Subject={}", email, subject);             log.error("Body:");             log.error(body);             return;         }         this.mailSender.send(message);     }     catch (MailException | UnsupportedEncodingException | MessagingException e) {         log.error(e.toString());         e.printStackTrace();     } }  private static String getFrom() {     Locale defaultLocale = Locale.getDefault();     ResourceBundle bundle = ResourceBundle.getBundle("messages", defaultLocale);     return bundle.getString("label.project.name"); }  protected static String getTestEmailAddress() {     return ResourceBundle.getBundle(AbstractEnvironment.ENVIRONMENT)             .getString("testEmailAddress"); }  protected static Boolean isTestMode() {     return Boolean.valueOf(ResourceBundle.getBundle(AbstractEnvironment.ENVIRONMENT)                                    .getString("redirectAllEmailsToTestEmailAddress")); }  @Autowired private JavaMailSenderImpl mailSender;  //setter needed for Junit public void setMailSender(JavaMailSenderImpl mailSender) {     this.mailSender = mailSender; }   
Original en ingles

I have a Spring @Service to asynchronously send emails. The part that seems to be a bit off to me is some code that is specific to our QA environment. We want to send and receive all emails through a test email account so that it does not impact live users if we work with real data imported to QA. I check for the environment and some settings in .properties files and adjust the outgoing email accordingly.

Is there a better way to handle this?

@Async public void send(String email, String subject, String body) {      if (email == null) {         log.error("Not sending; null input: email");         return;     }     try {         MimeMessage message = this.mailSender.createMimeMessage();         MimeMessageHelper helper = new MimeMessageHelper(message);         helper.setFrom(mailSender.getUsername(), getFrom());         helper.setReplyTo(mailSender.getUsername());         helper.setSubject(subject);          //HERE IS THE PART THAT'S IFFY:          if ("QA".equalsIgnoreCase(EmailManager.getEnvironmentName())) {             if (isTestMode()) {                 if (!email.equals(getTestEmailAddress())) {                     helper.setTo(getTestEmailAddress());                     body += "<br/>This email was originally intended for " + email +                             " but was redirected to " + getTestEmailAddress() + " for testing.";                     helper.setText(body, true); //HTML on                 }             }         }         else {             helper.setTo(email);             helper.setText(body, true); //HTML on         }          if (message == null) {             log.error("Email message to send is null.  Email={}, Subject={}", email, subject);             log.error("Body:");             log.error(body);             return;         }         this.mailSender.send(message);     }     catch (MailException | UnsupportedEncodingException | MessagingException e) {         log.error(e.toString());         e.printStackTrace();     } }  private static String getFrom() {     Locale defaultLocale = Locale.getDefault();     ResourceBundle bundle = ResourceBundle.getBundle("messages", defaultLocale);     return bundle.getString("label.project.name"); }  protected static String getTestEmailAddress() {     return ResourceBundle.getBundle(AbstractEnvironment.ENVIRONMENT)             .getString("testEmailAddress"); }  protected static Boolean isTestMode() {     return Boolean.valueOf(ResourceBundle.getBundle(AbstractEnvironment.ENVIRONMENT)                                    .getString("redirectAllEmailsToTestEmailAddress")); }  @Autowired private JavaMailSenderImpl mailSender;  //setter needed for Junit public void setMailSender(JavaMailSenderImpl mailSender) {     this.mailSender = mailSender; } 
        

Lista de respuestas

1
 
vote

Use la inyección de dependencia de la primavera más agresiva

Tienes derecho a sospechar sobre la lógica específica del medio ambiente. Pero estás de suerte. Este es uno de los problemas típicos que la primavera puede ayudarlo a resolver.

Una forma de resolver Esto es crear una interfaz para controlar la dirección de correo electrónico de destino e inyectar una implementación apropiada para el entorno. Por ejemplo:

  interface OutgoingEmailController {     void adjustOutgoingEmail(MimeMessageHelper helper, String email, String body); }   

Implementación para inyectar en QA:

  class QAOutgoingEmailController implements OutgoingEmailController {     @Override     public void adjustOutgoingEmail(MimeMessageHelper helper, String email, String body) {         if (isTestMode()) {             if (!email.equals(getTestEmailAddress())) {                 helper.setTo(getTestEmailAddress());                 body += "<br/>This email was originally intended for " + email +                         " but was redirected to " + getTestEmailAddress() + " for testing.";                 helper.setText(body, true); //HTML on             }         }     } }   

Implementación para inyectar en otros entornos:

  class CommonOutgoingEmailController implements OutgoingEmailController {     @Override     public void adjustOutgoingEmail(MimeMessageHelper helper, String email, String body) {         helper.setTo(email);         helper.setText(body, true);     } }   

En su código original, tendrá un 998877766555443333 y el código IFFY reemplazado con outgoingEmailController.adjustOutgoingEmail(helper, email, body); .

o algo así.

Otras observaciones

Es extraño que revise el null email al principio, compruebe si hay null body al final. Sería mejor mover el cheque en el cuerpo más adelante hasta el principio.

 

Use Spring's dependency injection more aggressively

You are right to be suspicious about hardcoded environment-specific logic. But you're in luck. This is one of the typical problems that Spring can help you solve.

One way to solve this is to create an interface for controlling the destination email address, and inject an implementation appropriate for the environment. For example:

interface OutgoingEmailController {     void adjustOutgoingEmail(MimeMessageHelper helper, String email, String body); } 

Implementation to inject in QA:

class QAOutgoingEmailController implements OutgoingEmailController {     @Override     public void adjustOutgoingEmail(MimeMessageHelper helper, String email, String body) {         if (isTestMode()) {             if (!email.equals(getTestEmailAddress())) {                 helper.setTo(getTestEmailAddress());                 body += "<br/>This email was originally intended for " + email +                         " but was redirected to " + getTestEmailAddress() + " for testing.";                 helper.setText(body, true); //HTML on             }         }     } } 

Implementation to inject in other environments:

class CommonOutgoingEmailController implements OutgoingEmailController {     @Override     public void adjustOutgoingEmail(MimeMessageHelper helper, String email, String body) {         helper.setTo(email);         helper.setText(body, true);     } } 

In your original code you will have an @Autowired OutgoingEmailController outgoingEmailController;, and the IFFY code replaced with outgoingEmailController.adjustOutgoingEmail(helper, email, body);.

Or something like that.

Other remarks

It's odd that you check for null email at the beginning but check for null body at the end. It would be better to move the check on the body further up to the beginning.

 
 
       
       

Relacionados problema

3  Inicialización de propiedades numéricas de un archivo de propiedades basadas en texto  ( Initialising numerical properties from a text based properties file ) 
Este es un instantáneo de datos de DataSource basado en el marco de primavera que lee sus propiedades del contexto marco de resorte, es decir, los valores son...

3  Validador para un formulario de registro de usuario  ( Validator for a user registration form ) 
En un formulario de registro de usuario, el validador actualmente comprueba no solo la entrada del usuario, sino también si el usuario existe o no. Esto parec...

-1  Cómo evitar el código duplicado debido a la imposibilidad de usar múltiples herencias  ( How to avoid duplicate code due to the impossibility of using multiple inheritan ) 
Estoy trabajando en una aplicación de primavera - Hibernate, y tengo una pregunta sobre cómo evitar correctamente el código duplicado y usar Hibernate, debido...

1  Aumento de rendimiento en la integración de primavera  ( Performance increase on spring integration ) 
He estado ejecutando un programa para leer un archivo con 6 millones de filas y validar cada línea y escribir la cadena que contiene el mensaje de validación ...

3  Personalizar los tipos de datos en un modelo generado con hibernación  ( Customize data types in a generated model with hibernate ) 
Tengo una aplicación de primavera / hibernación con la siguiente clase de dominio (código irrelevante despojado de brevedad): @Entity @Data public class Pr...

0  Breadcrumbs en primavera  ( Breadcrumbs in spring ) 
Las rutas de pan deberían verse así: Hogar y GT; Mobiles y amplificadores; Tabletas & gt; Teléfonos móviles & gt; Teléfono Super Duper Cada producto pertene...

0  Métodos de arranque de primavera para agregar y eliminar relaciones  ( Spring boot methods to add and remove relationships ) 
Tengo una aplicación de arranque de primavera y escribí una pieza de código para administrar las relaciones entre dos entidades. El código consiste principa...

1  Adaptador configurador web de seguridad de primavera  ( Spring security web configurer adapter ) 
chicos. El código a continuación es el adaptador web de seguridad de resorte. No me gusta el método de configuración (httsecurity) que genera la política de c...

1  Datos de primavera Redis - ¿Relaciones de objetos de mapeo?  ( Spring data redis mapping object relationships ) 
Estoy diseñando una aplicación que procesará un conjunto de mensajes de redes sociales que son publicados por los usuarios. Cada mensaje se califica y hay una...

2  Recoge mensajes de un trabajo para enviar en el cuerpo de un correo electrónico  ( Collect messages from a job to send in body of one email ) 
Tengo un servicio de primavera que llama algunos métodos para @Service @RequiredArgsConstructor @Slf4j public class CarService { private final CarRepo...




© 2022 respuesta.top Reservados todos los derechos. Centro de preguntas y respuestas reservados todos los derechos