27/04/2019

[Spring Boot] Send HTML email with attachment using Thymeleaf template

Thymeleaf provides a powerful and easy to use template engine that is effortlessly integrated in Spring and Spring Boot projects.

In this example we look at how to send HTML emails with attachments using a Thymeleaf template from a Spring Boot 2 project.

First of all these are the imports we need to add:

org.springframework.boot:spring-boot-starter-mail
org.springframework.boot:spring-boot-starter-thymeleaf




Then we can create HTML templates and put them under resources/templates folder. To change this default location, you can add the following line to you application.properties file:

spring.thymeleaf.prefix=classpath:/





Since Thymeleaf can be used for both emails and webpages templates, you might encouter errors if you also have HTML templates for your webpages under resources/static that you do not wish Thymeleaf to handle (even if you explicitly specify the classpath with the above property). This can be easily prevented by adding this line too:

spring.thymeleaf.enabled=false

Which does NOT disable Thymeleaf, simply it prevents it from trying to process every template-like file in the classpath. For more properties and their description, you can refer to the Thymeleaf section of the official Spring Boot documentation

You can test with a simple template such as:

 <!DOCTYPE html>  
 <html lang="en" xmlns="http://www.w3.org/1999/xhtml" xmlns:th="http://www.thymeleaf.org">  
 <head></head>  
 <body>  
 Hello <span th:text="${world}"></span>, <a th:href="${url}">This is a URL</a>  
 </body>  
 </html>  


And lastly you will need some code to prepare and send the email:

 package com.blogspot.groglogs.thymeleaf.email;  
   
 import java.util.Map;  
   
 import javax.mail.MessagingException;  
 import javax.mail.internet.MimeMessage;  
   
 import org.springframework.beans.factory.annotation.Autowired;  
 import org.springframework.core.io.ByteArrayResource;  
 import org.springframework.mail.javamail.JavaMailSender;  
 import org.springframework.mail.javamail.MimeMessageHelper;  
 import org.springframework.stereotype.Component;  
 import org.thymeleaf.TemplateEngine;  
 import org.thymeleaf.context.Context;  
   
 @Component  
 public class EmailService {  
   
   @Autowired  
   public JavaMailSender emailSender;  
   
   @Autowired  
   private TemplateEngine templateEngine;  
   
   //process the desired template and replace all placeholders with the values passed via the input Map  
   private String build(String template, Map<String, String> variables) {  
     Context context = new Context();  
     for (Map.Entry<String, String> entry : variables.entrySet()) {  
       context.setVariable(entry.getKey(), entry.getValue());  
     }  
     return templateEngine.process(template, context);  
   }  
       
   public void sendHTMLMessageWithAttachments(String to, String subject, String template,   
                  Map<String, String> variables, String fileName,   
                  byte[] file)   
   throws MessagingException {  
   
     String content = build(template, variables);  
   
     MimeMessage message = emailSender.createMimeMessage();  
   
     MimeMessageHelper helper = new MimeMessageHelper(message, true);  
     helper.setTo(to);  
     helper.setSubject(subject);  
     helper.setText(content, true);  
     helper.addAttachment(fileName, new ByteArrayResource(file));  
     emailSender.send(helper.getMimeMessage());  
   }  
 }  
   


Then all you need to do to correctly invoke the method is to prepare a Map containing all the values to use to replace the template placeholders and pass it to the sendHTMLMessageWithAttachments method alongside the template to use (the file name minus the extension) and the file to attach.

No comments:

Post a Comment

With great power comes great responsibility