En este post, vamos a entender como enviar un email con Spring Boot.
La dependencia necesaria
Para enviar un email, se necesita esta dependencia.
build.gradle
implementation 'org.springframework.boot:spring-boot-starter-mail'
testImplementation 'org.springframework.boot:spring-boot-starter-test'
La configuración para enviar emails en Spring
Nosotros necesitamos definir JavaMailSender si queremos establecer las propiedades programáticamente.
Tú puedes usar JavaMailSenderImpl que implementa JavaMailSender para definir la configuración del servidor de email. Por ejemplo para Gmail, la configuración podría verse así:
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.mail.javamail.JavaMailSender;
import org.springframework.mail.javamail.JavaMailSenderImpl;
import java.util.Properties;
@Configuration
public class MailSenderConfig {
@Bean("javaMailSender")
public JavaMailSender javaMailSender() {
JavaMailSenderImpl sender = new JavaMailSenderImpl();
sender.setHost("smtp.gmail.com");
sender.setPort(587);
sender.setUsername("user@gmail.com");
sender.setPassword("password");
Properties props = sender.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 sender;
}
}
Observa. Para usar los servicios de Google SMTP tu necesitas crear una única “app password” para el servicio.
https://support.google.com/accounts/answer/185833?hl=en
Configuración usando properties para enviar e-mails en Spring
Antes, nosotros definimos la configuración cargando las propiedades en la JavaMailSenderImpl class.
Sin embargo, podemos saltar esto y definir las propiedades directamente en el application.properties file.
Si tú defines las propiedades, sin crear el ‘bean config’, Spring creará la clase JavaMailSenderImpl por ti con dichas propiedades.
spring.mail.host=smtp.gmail.com
spring.mail.port=587
spring.mail.username=user@gmail.com
spring.mail.password=password
spring.mail.properties.mail.smtp.auth=true
spring.mail.properties.mail.smtp.starttls.enable=true
Enviando un email con Spring
Puedes enviar un email simple, solo texto.
La class SimpleMailMessage provee un modelo simple para enviar mensajes de solo-texto.
SimpleMailMessage message = new SimpleMailMessage();
message.setFrom(from);
message.setTo(to);
message.setSubject(subject);
message.setText(text);
mailSender.send(message);
También, puedes enviar email con archivos adjuntos.
Para enviar e-mails con archivos adjuntos necesitas dos clases.
MimeMessage te permite el agregado de archivos adjuntos y MimeMessageHelper te ayuda a crear el mail.
MimeMessage message = mailSender.createMimeMessage();
MimeMessageHelper helper = new MimeMessageHelper(message, true);
helper.setFrom(from);
helper.setTo(to);
helper.setSubject(subject);
helper.setText(text);
helper.addAttachment(attachName, inputStream);
mailSender.send(message);
Si tu quieres, pueden agregar HTML tags.
Por ejemplo, aquí nosotros agregamos un texto con un tag HTML de negrita.
MimeMessage message = mailSender.createMimeMessage();
MimeMessageHelper helper = new MimeMessageHelper(message, true);
helper.setFrom(from);
helper.setTo(to);
helper.setSubject(subject);
helper.setText("<b>bold message</b>", true); // text with HTML tags
helper.addAttachment(attachName, inputStream);
mailSender.send(message);
MIME message significa “Multipurpose Internet Mail Extensions”. Con MIME messages tu puedes enviar HTML, y agregar archivos (text, audio, images, etc).
Resumen de las clases que usamos
- JavaMailSender: interface para configurar Spring Email
- JavaMailSenderImpl: implementación de JavaMailSender
- SimpleMailMessage: modelo para completar los atributos necesarios para enviar un email.
- MimeMessage: una class que representa un mensaje de tipo MIME.
- MimeMessageHelper: una clase de ayuda para crear mensajes MIME.
Ejemplo de un servicio usando JavaMailSender
Aquí nosotros creamos un servicio y usamos JavaMailSender que definimos previamente.
@Service
public class EmailService {
private JavaMailSender mailSender;
public EmailService(JavaMailSender mailSender) {
this.mailSender = mailSender;
}
public void send(String from, String to, String subject, String text) {
SimpleMailMessage message = new SimpleMailMessage();
message.setFrom(from);
message.setTo(to);
message.setSubject(subject);
message.setText(text);
mailSender.send(message);
}
public void sendWithAttach(String from, String to, String subject,
String text, String attachName,
InputStreamSource inputStream) throws MessagingException {
MimeMessage message = mailSender.createMimeMessage();
MimeMessageHelper helper = new MimeMessageHelper(message, true);
helper.setFrom(from);
helper.setTo(to);
helper.setSubject(subject);
helper.setText(text, true);
helper.addAttachment(attachName, inputStream);
mailSender.send(message);
}
}
Testeando nuestro Servicio de Email
Con el objetivo de chequear la funcionalidad de nuestro servicio, vamos a utilizar https://greenmail-mail-test.github.io/greenmail/
GreenMail es un open-source framework que provee test servers para validar nuestro email service construido.
build.gradle
implementation 'org.springframework.boot:spring-boot-starter-mail'
testImplementation 'org.springframework.boot:spring-boot-starter-test'
testImplementation 'com.icegreen:greenmail-junit5:1.6.9'
Vamos a definir las propiedades de test para GreenMail.
## test properties for test email Greenmail
spring.mail.host=localhost
spring.mail.port=3025
spring.mail.username=user@gmail.com
spring.mail.password=password
Test usando GreenMail para validar EmailService
import com.icegreen.greenmail.configuration.GreenMailConfiguration;
import com.icegreen.greenmail.junit5.GreenMailExtension;
import com.icegreen.greenmail.util.ServerSetupTest;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.extension.RegisterExtension;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.core.io.ClassPathResource;
import org.springframework.core.io.FileSystemResource;
import javax.mail.internet.MimeMessage;
import java.io.File;
import static org.junit.jupiter.api.Assertions.assertEquals;
@SpringBootTest
class EmailServiceTest {
@RegisterExtension
static GreenMailExtension greenMail = new GreenMailExtension(ServerSetupTest.SMTP)
.withConfiguration(GreenMailConfiguration
.aConfig().withUser("user@gmail.com", "password"));
@Autowired
private EmailService emailService;
@Test
void send() throws Exception {
emailService.send("gus@gmail.com", "jhon@gmail.com",
"Hello", "How are you?");
MimeMessage[] receivedMessages = greenMail.getReceivedMessages();
MimeMessage receivedMessage = receivedMessages[0];
assertEquals("gus@gmail.com", receivedMessage.getFrom()[0].toString());
assertEquals("jhon@gmail.com", receivedMessage.getAllRecipients()[0].toString());
assertEquals("Hello", receivedMessage.getSubject().trim());
assertEquals("How are you?", receivedMessage.getContent().toString().trim());
// others test assertions with receivedMessage..
}
@Test
void sendWithAttach() throws Exception {
ClassPathResource classPathResource = new ClassPathResource("info.txt");
File file = classPathResource.getFile();
FileSystemResource fileResource = new FileSystemResource(file);
emailService.sendWithAttach("gus@gmail.com", "jhon@gmail.com",
"Hello", "How are you?", "info.txt", fileResource);
MimeMessage[] receivedMessages = greenMail.getReceivedMessages();
MimeMessage receivedMessage = receivedMessages[0];
assertEquals("gus@gmail.com", receivedMessage.getFrom()[0].toString());
assertEquals("jhon@gmail.com", receivedMessage.getAllRecipients()[0].toString());
assertEquals("Hello", receivedMessage.getSubject().trim());
// others test assertions with receivedMessage..
}
}
Conclusión:
En este post nosotros aprendimos como configurar Java Email Sender con Spring Boot usando ‘beans’ configuration y property files. También entendimos como crear un JUnit test con GreenMail.
El código:
El código lo encuentras en GitHub.
https://github.com/gustavopeiretti/spring-boot-examples/tree/master/spring-boot-email