Spring Boot Email using Thymeleaf with Example
Let us see how to send HTML emails using thymeleaf templates in a spring boot application.
Things got easier with spring boot and thymeleaf template engine. As you know, Thymeleaf is used as a View in Spring MVC applications. However, do you know you can use the same template Engine for generating rich HTML emails? Let’s take a look at this example.
Setup Email and Thymeleaf starters
To achieve this, we need two starters from spring boot. Including the below to our pom.xml will enable JavaMail and Thymeleaf support for our project.
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-mail</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-thymeleaf</artifactId>
</dependency>
Code language: HTML, XML (xml)
In my example, I have also included spring-boot-starter-web so that I can trigger the emails via an API call. However, it is up to you how you want to wire this in your own application.
Configuring Mail server properties
By including the above dependencies, You are letting Spring Boot configure the JavaMail and thymeleaf template Engine configurations. For Thymeleaf, you don’t need to add any additional configurations to your project. However, JavaMail expects a few configurations in order to initiate the JavaMailSender
object via auto-configuration. A sample configuration is given below.
spring.mail.username=[email protected]
spring.mail.password=*******
spring.mail.host=smtp.gmail.com
spring.mail.port=587
spring.mail.protocol=smtp
spring.mail.properties.mail.smtp.auth=true
spring.mail.properties.mail.smtp.starttls.enable=true
Code language: Properties (properties)
Note that I have used GMAIL’s SMTP server and my own username and password for this demo. In most cases, you are developing for an organization and would need to change the host based on your organization’s settings.
If you wish to use your own GMAIL account, then you may need to enable access to less secure apps for your account
Spring Boot Email Service
In addition to that, let’s set up a simple EmailService.
@Service
public class EmailService {
private final JavaMailSender javaMailSender;
public EmailService(JavaMailSender javaMailSender) {
this.javaMailSender = javaMailSender;
}
public void sendMail(User user) throws MessagingException {
javax.mail.internet.MimeMessage mimeMessage = javaMailSender.createMimeMessage();
MimeMessageHelper helper = new MimeMessageHelper(mimeMessage);
helper.setSubject("Welcome " + user.getName());
String html = "<!doctype html>\n" +
"<html lang=\"en\" xmlns=\"http://www.w3.org/1999/xhtml\"\n" +
" xmlns:th=\"http://www.thymeleaf.org\">\n" +
"<head>\n" +
" <meta charset=\"UTF-8\">\n" +
" <meta name=\"viewport\"\n" +
" content=\"width=device-width, user-scalable=no, initial-scale=1.0, maximum-scale=1.0, minimum-scale=1.0\">\n" +
" <meta http-equiv=\"X-UA-Compatible\" content=\"ie=edge\">\n" +
" <title>Email</title>\n" +
"</head>\n" +
"<body>\n" +
"<div>Welcome <b>" + user.getName() + "</b></div>\n" +
"\n" +
"<div> Your username is <b>" + user.getUsername() + "</b></div>\n" +
"</body>\n" +
"</html>\n";
helper.setText(html, true);
helper.setTo(user.getEmail());
javaMailSender.send(mimeMessage);
}
}
Code language: Java (java)
This code does its job well and has no problem except it is messy and hard to change in the future. When there are large emails with too many variables, This class will become a developer’s nightmare. Here comes thymeleaf for help.
Thymeleaf templates for HTML emails
Thymeleaf is most known for its use as a view in MVC applications. However, it is basically a templating engine that generates content based on a template and context variables. So it is understandable to use the same technology for creating customized HTML email content for our spring boot application. Thanks to spring boot, This template engine is auto-configured by default and no extra configuration is needed.
Thymeleaf by default picks up its templates from src/main/resources/templates/ directory. So let’s move our HTML template there and call it welcome.html.
<!doctype html>
<html lang="en" xmlns="http://www.w3.org/1999/xhtml"
xmlns:th="http://www.thymeleaf.org">
<head>
<meta charset="UTF-8">
<meta name="viewport"
content="width=device-width, user-scalable=no, initial-scale=1.0, maximum-scale=1.0, minimum-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>Email</title>
</head>
<body>
<div>Welcome <b th:text="${user.name}"></b></div>
<div> Your username is <b th:text="${user.username}"></b></div>
</body>
</html>
Code language: HTML, XML (xml)
Spring Boot Email service with Thymeleaf
In my case, I have created a directory under templates called emails and placed my template file there. Now, let us re-write our EmailService
by autowiring templateEngine
. By eliminating the messy template part, the code becomes cleaner and easy to maintain.
@Service
public class EmailService {
private final TemplateEngine templateEngine;
private final JavaMailSender javaMailSender;
public EmailService(TemplateEngine templateEngine, JavaMailSender javaMailSender) {
this.templateEngine = templateEngine;
this.javaMailSender = javaMailSender;
}
public String sendMail(User user) throws MessagingException {
Context context = new Context();
context.setVariable("user", user);
String process = templateEngine.process("emails/welcome", context);
javax.mail.internet.MimeMessage mimeMessage = javaMailSender.createMimeMessage();
MimeMessageHelper helper = new MimeMessageHelper(mimeMessage);
helper.setSubject("Welcome " + user.getName());
helper.setText(process, true);
helper.setTo(user.getEmail());
javaMailSender.send(mimeMessage);
return "Sent";
}
}
Code language: Java (java)
For the demo, I have written an API that takes a user object and calls EmailService.sendMail(User user)
.
@RequestMapping(value = "/email", method = RequestMethod.POST)
@ResponseBody
public String sendMail(@RequestBody User user)throws MessagingException{
emailService.sendMail(user);
return "Email Sent Successfully.!";
}
Code language: Java (java)
Email Result
If you have done all the above properly, then you would get the following as the result.
$ curl -X POST "http://localhost:8080/email" \
-H "Content-Type: application/json" \
--data '{ "name": "John Doe", "username": "jd01", "email": "[email protected]" }'
HTTP/1.1 200
Content-Type: text/plain;charset=UTF-8
Content-Length: 25
Date: Tue, 08 Sep 2020 09:17:06 GMT
Keep-Alive: timeout=60
Connection: keep-alive
Email Sent Successfully.!
Code language: Bash (bash)
You can see the email at the disposable email box [email protected]
.
Note that You can further improve this service by adding a new parameter for template name in the
sendEmail
method.
public void sendMail(User user, String templateName)
This way similar templates can use same method. For instance, User addition, deletion and modification can use same user object with different template files.
Conclusion
So That’s it for sending rich HTML emails from Spring Boot using thymeleaf templates. Take a look at our write-ups related to this one.
I found the following way to send email with this project example:
1. run this command from terminal:
docker run -d –restart always –name mail -p 25:25 bytemark/smtp
2. change “application.properties” file to this:
#[email protected]
#spring.mail.password=secretpassword
spring.mail.host=localhost
spring.mail.port=25
spring.mail.protocol=smtp
#spring.mail.properties.mail.smtp.auth=false
#spring.mail.properties.mail.smtp.starttls.enable=false
correction the acutal error is:
Error resolving template [WelcomeTemplate], template might not exist or might not be accessible by any of the configured Template Resolvers.
I’m using spring boot but not able to send emails using template.
Getting below error in template resolution:
An error happened during template parsing (template: \”class path resource [templates/WelcomeTemplate.html]\”)
Can you share the code / repository so that I can check if any configuration is missisng on my side?
You can find the sample here at https://github.com/springhow/spring-boot-email-thymeleaf