In this post, we will understand how to send an email with Spring Boot.
The dependency necessary
In order to send an email, you need this dependency
build.gradle
implementation 'org.springframework.boot:spring-boot-starter-mail'
testImplementation 'org.springframework.boot:spring-boot-starter-test'
The configuration for sending emails in Spring
We need to define the JavaMailSender if we want to set the properties programmatically.
You can use JavaMailSenderImpl which implements JavaMailSender to define the mail server configuration. For example, for Gmail, the configuration could look like this:
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;
}
}
Note. To use Google SMTP services you need to create a unique “app password” for the service.
https://support.google.com/accounts/answer/185833?hl=en
Configuration using properties for sending e-mails in Spring
In the previous section, we defined the configuration by loading the properties in JavaMailSenderImpl class.
However, we can skip this and define the properties directly in the http://application.properties file.
If you only set the properties, without creating the ‘bean config’, Spring will create the JavaMailSenderImpl for you.
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
Sending an email with Spring
You can send a simple email, only text.
The SimpleMailMessage class provides a simple model for sending text-only messages.
SimpleMailMessage message = new SimpleMailMessage();
message.setFrom(from);
message.setTo(to);
message.setSubject(subject);
message.setText(text);
mailSender.send(message);
Also, you can send an email with attached files.
To send e-mails with attachments you need two classes.
MimeMessage allows the addition of attachments and MimeMessageHelper helps us create the 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);
If you want, you can add HTML tags.
For example, here we add a text with a bold HTML tag.
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 means “Multipurpose Internet Mail Extensions”. With MIME messages you can send HTML texts, and attach files (text, audio, images, etc)
Summary of classes involved
- JavaMailSender: interface to configure Spring Email
- JavaMailSenderImpl: implementation of JavaMailSender
- SimpleMailMessage: model to complete attributes necessaries to send an email.
- MimeMessage: a class that represents a MIME message.
- MimeMessageHelper: a helper class to create a MIME message.
Example of service using JavaMailSender
Here we create a service and use JavaMailSender that we define in our previous configuration.
@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);
}
}
Testing our Email Service
In order to check the functionality of our service we are going to use https://greenmail-mail-test.github.io/greenmail/
GreenMail is an open-source framework that provides servers for testing our mail services.
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'
We will define the properties to test with 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
Email Service Test using GreenMail to validate 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..
}
}
Conclusion:
In this post we learn how to configure the Java Email Sender with Spring Boot using ‘beans’ configuration and property files. We also understood how to create a JUnit test with GreenMail.
The code :
As always you can see this code in GitHub.
https://github.com/gustavopeiretti/spring-boot-examples/tree/master/spring-boot-email