🏠Spring BootSpring Boot Email using Thymeleaf with Example

Spring Boot Email using Thymeleaf with Example

Spring Boot Thymeleaf

In this post, We will 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=springhow.com@gmail.com 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 setup 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 a template and a set of 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/java/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, Lets 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 an 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": "john.doe@yopmail.com" }' 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 john.doe@yopmail.com.

Screenshot of the mail received by this disposable mailbox

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.

Similar Posts

Leave a Reply

Your email address will not be published. Required fields are marked *