Send Email with Thymeleaf template in Spring Boot
In this article, we’ll learn how to compose emails using Thymeleaf template and send emails using spring framework’s JavaMailSender.
Overview
Thymeleaf is a modern sever-side Java template engine. Thymeleaf is mostly used to build elegant HTML templates. Spring boot web MVC provides good integration with Thymeleaf for server-side view development.
We will first use Thymeleaf templates to compose HTML email messages and then we will use spring framework’s JavaMailSender to send email.
Project Setup
For initial setup of your Spring Boot project, you should use Spring Initializr. Choose the Java Mail Sender and Thymeleaf as dependencies.
You can use either Maven or Gradle build tool of your choice:-
Maven Project
Click on the below link to generate a Maven project with pre-selected required dependencies:-
https://start.spring.io/#!type=maven-project&language=java&platformVersion=2.6.1&packaging=jar&jvmVersion=11&groupId=com.example&artifactId=email&name=email&description=Send%20Email%20with%20Thymeleaf%20Templates&packageName=com.example.email&dependencies=mail,thymeleaf
pom.xml
<!-- to send email using java Mail and spring framework's JavaMailSender -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-mail</artifactId>
</dependency>
<!-- to create email templates using Thymeleaf server-side Java template engine -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-thymeleaf</artifactId>
</dependency>
<!-- to write test class using junit jupiter -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
Gradle Project
Click on the below link to generate a Gradle project with pre-selected required dependencies:-
build.gradle
dependencies {
// to send email using java Mail and spring framework's JavaMailSender
implementation 'org.springframework.boot:spring-boot-starter-mail'
// to create email templates using Thymeleaf server-side Java template engine
implementation 'org.springframework.boot:spring-boot-starter-thymeleaf'
// to write test class using junit jupiter
testImplementation 'org.springframework.boot:spring-boot-starter-test'
}
Project Structure
A typical project structure for writing an email service looks like this:-
📖springboot-email
📁src
📁main
📁java
📦com.example.email
📦config
📄ThymeleafTemplateConfig
📦model
📄Email
📦service
📄EmailSenderService
EmailApplication
📁resources
📁templates
📄welcome-email.html
⚙application.yml
pom.xml
build.gradle
Thymeleaf Email Template Configuration
In order to process our email templates, we will configure a SpringTemplateEngine
:-
package com.example.email.config;
@Configuration
public class ThymeleafTemplateConfig {
@Bean
public SpringTemplateEngine springTemplateEngine() {
SpringTemplateEngine springTemplateEngine = new SpringTemplateEngine();
springTemplateEngine.addTemplateResolver(emailTemplateResolver());
return springTemplateEngine;
}
public ClassLoaderTemplateResolver emailTemplateResolver() {
ClassLoaderTemplateResolver emailTemplateResolver = new ClassLoaderTemplateResolver();
emailTemplateResolver.setPrefix("/templates/");
emailTemplateResolver.setSuffix(".html");
emailTemplateResolver.setTemplateMode(TemplateMode.HTML);
emailTemplateResolver.setCharacterEncoding(StandardCharsets.UTF_8.name());
emailTemplateResolver.setCacheable(false);
return emailTemplateResolver;
}
}
This template configuration will look for templates in src/main/resources/templates/
folder with .html
extension.
Let’s create our welcome email HTML template with Thymeleaf:-
src/main/resources/templates/welcome-email.html
<!DOCTYPE html>
<html xmlns:th="http://www.thymeleaf.org">
<head>
<title th:remove="all">Template for HTML email</title>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8"/>
</head>
<body>
<p>
Hello, <span th:text="${name}">Peter Static</span>!
</p>
<p th:if="${name.length() > 10}">
Wow! You've got a long name (more than 10 chars)!
</p>
<p>
You have been successfully subscribed to the <b>CodingNConcepts</b> on
<span th:text="${subscriptionDate}">28-12-2012</span>
</p>
<p>We write on following technologies:-</p>
<ul th:remove="all-but-first">
<li th:each="tech : ${technologies}" th:text="${tech}">Java</li>
<li>JavaScript</li>
<li>CSS</li>
</ul>
<p>
Regards, <br/>
<em>The CodingNConcepts Team</em>
</p>
</body>
</html>
JavaMailSender Configuration
Provide the SMTP (Mail) server configuration in application.yml
or application.properties
file to initialize JavaMailSender
, which we will use to send emails.
application.yml
spring:
mail:
default-encoding: UTF-8
host: smtp.gmail.com
port: 587
username: lahoti.ashish20@gmail.com
password: #gmail_app_password
properties:
mail:
smtp:
auth: true
starttls:
enable: true
debug: true
protocol: smtp
test-connection: false
Some of the popular SMTP (Mail) server details are as follows:-
Host | Port | Authentication | Username | Password | |
---|---|---|---|---|---|
Gmail | smtp.gmail.com | 587 (TLS) | true | example@gmail.com | Generate Gmail App Password |
Yahoo | smtp.mail.yahoo.com | 465 (SSL) or 587 (TLS) | true | example@yahoo.com | Generate Yahoo App Password |
If you want to use Gmail or Yahoo server to send email then you need a valid username and password for authentication. You can use your existing email address for e.g. lahoti.ashish20@gmail.com as username but password isn’t the same as your email password. You need to generate an app password from your mail account to use with SMTP (Mail) server.
If you are working in an organization then you might need your organization SMTP server details to configure.
Service to Send Email
Let’s use SpringTemplateEngine
to compose email and JavaMailSender
to send email in our service class:-
package com.example.email.service;
@Service
@RequiredArgsConstructor
@Slf4j
public class EmailSenderService {
private final JavaMailSender emailSender;
private final SpringTemplateEngine templateEngine;
public void sendHtmlMessage(Email email) throws MessagingException {
MimeMessage message = emailSender.createMimeMessage();
MimeMessageHelper helper = new MimeMessageHelper(message, MimeMessageHelper.MULTIPART_MODE_MIXED_RELATED, StandardCharsets.UTF_8.name());
Context context = new Context();
context.setVariables(email.getProperties());
helper.setFrom(email.getFrom());
helper.setTo(email.getTo());
helper.setSubject(email.getSubject());
String html = templateEngine.process(email.getTemplate(), context);
helper.setText(html, true);
log.info("Sending email: {} with html body: {}", email, html);
emailSender.send(message);
}
}
Test Service to Send Email
Now its time to test sending email message composed using welcome-email.html
thymeleaf template
@SpringBootTest
public class EmailSenderServiceTest {
@Autowired
private EmailSenderService emailSenderService;
@Test
public void sendHtmlMessageTest() throws MessagingException {
Email email = new Email();
email.setTo("lahoti.ashish20@gmail.com");
email.setFrom("lahoti.ashish20@gmail.com");
email.setSubject("Welcome Email from CodingNConcepts");
email.setTemplate("welcome-email.html");
Map<String, Object> properties = new HashMap<>();
properties.put("name", "Ashish");
properties.put("subscriptionDate", LocalDate.now().toString());
properties.put("technologies", Arrays.asList("Python", "Go", "C#"));
email.setProperties(properties);
Assertions.assertDoesNotThrow(() -> emailSenderService.sendHtmlMessage(email));
}
}
Voilà! Message arrived in my mailbox:-
Download the complete source code for the examples in this post from github/springboot-email