Send Email with Thymeleaf template in Spring Boot Send Email with Thymeleaf template in Spring Boot

Page content

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:-

https://start.spring.io/#!type=gradle-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

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.htmlapplication.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:-

Email 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:-

Send Email using Thymeleaf template

Download the complete source code for the examples in this post from github/springboot-email