Guía de Spring Email

1. Información general

En este artículo, analizaremos los pasos necesarios para enviar correos electrónicos tanto desde una aplicación simple de Spring como desde una aplicación Spring Boot, la primera usando la biblioteca JavaMail y la última usando la dependencia spring-boot-starter-mail .

2. Dependencias de Maven

Primero, necesitamos agregar las dependencias a nuestro pom.xml .

2.1. Primavera

Para usar en el marco simple de vainilla Spring, agregaremos:

 org.springframework spring-context-support 5.2.8.RELEASE 

La última versión se puede encontrar aquí.

2.2. Bota de primavera

Y para Spring Boot:

 org.springframework.boot spring-boot-starter-mail 2.2.5.RELEASE 

La última versión está disponible en el repositorio de Maven Central.

3. Propiedades del servidor de correo

Las interfaces y clases para el soporte de correo Java en el marco de Spring están organizadas de la siguiente manera:

  1. Interfaz de MailSender : la interfaz de nivel superior que proporciona una funcionalidad básica para enviar correos electrónicos sencillos
  2. Interfaz JavaMailSender : la subinterfaz del MailSender anterior. Admite mensajes MIME y se usa principalmente junto con laclase MimeMessageHelper para la creación de un MimeMessage . Se recomienda utilizar elmecanismo MimeMessagePreparator con esta interfaz
  3. Clase JavaMailSenderImpl : proporciona una implementación de lainterfaz JavaMailSender . Es compatible con MimeMessage y SimpleMailMessage
  4. Clase SimpleMailMessage : se utiliza para crear un mensaje de correo simple que incluye los campos de, para, cc, asunto y texto
  5. Interfaz MimeMessagePreparator : proporciona una interfaz de devolución de llamada para la preparación de mensajes MIME
  6. Clase MimeMessageHelper : clase auxiliar para la creación de mensajes MIME. Ofrece soporte para imágenes, archivos adjuntos de correo típicos y contenido de texto en un diseño HTML

En las siguientes secciones, mostramos cómo se utilizan estas interfaces y clases.

3.1. Propiedades del servidor de correo de Spring

Las propiedades de correo que se necesitan especificar, por ejemplo, el servidor SMTP, se pueden definir utilizando JavaMailSenderImpl .

Por ejemplo, para Gmail, esto se puede configurar como se muestra a continuación:

@Bean public JavaMailSender getJavaMailSender() { JavaMailSenderImpl mailSender = new JavaMailSenderImpl(); mailSender.setHost("smtp.gmail.com"); mailSender.setPort(587); mailSender.setUsername("[email protected]"); mailSender.setPassword("password"); Properties props = mailSender.getJavaMailProperties(); props.put("mail.transport.protocol", "smtp"); props.put("mail.smtp.auth", "true"); props.put("mail.smtp.starttls.enable", "true"); props.put("mail.debug", "true"); return mailSender; } 

3.2. Propiedades del servidor de correo Spring Boot

Una vez que la dependencia está en su lugar, el siguiente paso es especificar las propiedades del servidor de correo en el archivo application.properties usando el espacio de nombres spring.mail. * .

Por ejemplo, las propiedades del servidor SMTP de Gmail se pueden especificar como:

spring.mail.host=smtp.gmail.com spring.mail.port=587 spring.mail.username= spring.mail.password= spring.mail.properties.mail.smtp.auth=true spring.mail.properties.mail.smtp.starttls.enable=true 

Algunos servidores SMTP requieren una conexión TLS, por lo que la propiedad spring.mail.properties.mail.smtp.starttls.enable se utiliza para habilitar una conexión protegida por TLS.

3.2.1. Propiedades de SMTP de Gmail

Podemos enviar un correo electrónico a través del servidor SMTP de Gmail. Consulte la documentación para ver las propiedades del servidor SMTP de correo saliente de Gmail.

Nuestra aplicación. El archivo de propiedades ya está configurado para usar Gmail SMTP (ver la sección anterior).

Tenga en cuenta que la contraseña de su cuenta no debe ser una contraseña normal, sino una contraseña de aplicación generada para su cuenta de Google. Siga este enlace para ver los detalles y generar su contraseña de la aplicación de Google.

3.2.2. Propiedades de SES SMTP

Para enviar correos electrónicos utilizando el servicio Amazon SES, configure su application.properties como lo hacemos a continuación:

spring.mail.host=email-smtp.us-west-2.amazonaws.com spring.mail.username=username spring.mail.password=password spring.mail.properties.mail.transport.protocol=smtp spring.mail.properties.mail.smtp.port=25 spring.mail.properties.mail.smtp.auth=true spring.mail.properties.mail.smtp.starttls.enable=true spring.mail.properties.mail.smtp.starttls.required=true

Tenga en cuenta que Amazon requiere que verifique sus credenciales antes de usarlas. Siga el enlace para verificar su nombre de usuario y contraseña.

4. Envío de correo electrónico

Una vez que la gestión y la configuración de las dependencias están en su lugar, podemos usar el JavaMailSender mencionado anteriormente para enviar un correo electrónico.

Dado que tanto el marco simple de vainilla Spring como la versión de arranque manejan la composición y el envío de correos electrónicos de manera similar, no tendremos que distinguir entre los dos en las subsecciones siguientes.

4.1. Envío de correos electrónicos sencillos

Primero redactemos y enviemos un mensaje de correo electrónico simple sin ningún archivo adjunto:

@Component public class EmailServiceImpl implements EmailService { @Autowired private JavaMailSender emailSender; public void sendSimpleMessage( String to, String subject, String text) { ... SimpleMailMessage message = new SimpleMailMessage(); message.setFrom("[email protected]"); message.setTo(to); message.setSubject(subject); message.setText(text); emailSender.send(message); ... } }

Tenga en cuenta que, aunque no es obligatorio proporcionar la dirección de remitente, muchos servidores SMTP rechazarían dichos mensajes. Es por eso que usamos la dirección de correo electrónico [email protected] en nuestra implementación de EmailService .

4.2. Envío de correos electrónicos con archivos adjuntos

A veces, la mensajería simple de Spring no es suficiente para nuestros casos de uso.

For example, we want to send an order confirmation email with an invoice attached. In this case, we should use a MIME multipart message from JavaMail library instead of SimpleMailMessage. Spring supports JavaMail messaging with the org.springframework.mail.javamail.MimeMessageHelper class.

First of all, we'll add a method to the EmailServiceImpl to send emails with attachments:

@Override public void sendMessageWithAttachment( String to, String subject, String text, String pathToAttachment) { // ... MimeMessage message = emailSender.createMimeMessage(); MimeMessageHelper helper = new MimeMessageHelper(message, true); helper.setFrom("[email protected]"); helper.setTo(to); helper.setSubject(subject); helper.setText(text); FileSystemResource file = new FileSystemResource(new File(pathToAttachment)); helper.addAttachment("Invoice", file); emailSender.send(message); // ... }

4.3. Simple Email Template

SimpleMailMessage class supports text formatting. We can create a template for emails by defining a template bean in our configuration:

@Bean public SimpleMailMessage templateSimpleMessage() { SimpleMailMessage message = new SimpleMailMessage(); message.setText( "This is the test email template for your email:\n%s\n"); return message; }

Now we can use this bean as a template for email and only need to provide the necessary parameters to the template:

@Autowired public SimpleMailMessage template; ... String text = String.format(template.getText(), templateArgs); sendSimpleMessage(to, subject, text);

5. Handling Send Errors

JavaMail provides SendFailedException to handle situations when a message cannot be sent. But it is possible that you won't get this exception while sending an email to the incorrect address. The reason is the following:

The protocol specs for SMTP in RFC 821 specifies the 550 return code that SMTP server should return when attempting to send an email to the incorrect address. But most of the public SMTP servers don't do this. Instead, they send a “delivery failed” email to your box, or give no feedback at all.

For example, Gmail SMTP server sends a “delivery failed” message. And you get no exceptions in your program.

So, there are few options you can go through to handle this case:

  1. Catch the SendFailedException, which can never be thrown
  2. Verifique el buzón de correo del remitente en el mensaje de "entrega fallida" durante algún tiempo. Esto no es sencillo y el período de tiempo no está determinado
  3. Si su servidor de correo no da ningún comentario, no puede hacer nada

6. Conclusión

En este artículo rápido, mostramos cómo configurar y enviar correos electrónicos desde una aplicación Spring Boot.

La implementación de todos estos ejemplos y fragmentos de código se puede encontrar en GitHub.