Suppose our application needs to email in text or HTML format; how can we do that without changing a lot of codes? We use templates! Spring Boot makes it a lot easier working with Apache FreeMarker with FreeMarker Starter POMs. This quickstart post shows how to configure and use FreeMarker with Spring Boot. We know applications can exchange information in various formats, but the data may be the same. For instance, we want to send emails in either text or HTML format, although the content may be the same in either form.
About Template Engines like Apache FreeMarker
Template engines like Apache FreeMarker and Thymeleaf allow applications to format output quickly using templates. These engines use templates that dictate how to display the data. They take these templates, map data to specific locations, and fill them in before generating the final output.
Spring Boot And Apache FreeMarker Starter POM
To use FreeMarker in Spring Boot, we can use the following starter POM.
1 2 3 4 | <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-freemarker</artifactId> </dependency> |
Generate Email Using Template File
By default, Spring Boot looks for the template files in the /resources/templates directory. To generate an email from a template, we need to craft and use a .flth file. Suppose we have the following template content, which is essentially an HTML with a FreeMarker-specific placeholder ${name}.
1 2 3 4 5 6 | <html> <head></head> <body> <p>Dear ${name}</p> </body> </html> |
Then, we can use the following codes anywhere in our codebase.
1 2 3 4 5 | Map<String, Object> model = new HashMap<>(); model.put("name", "turreta.com"); String email = FreeMarkerTemplateUtils.processTemplateIntoString( fmConfiguration.getTemplate("email-template.flth"), model); |
Note the Map instance we pass to the processTemplateIntoString method. The map has an entry with a key name whose value is turreta.com. Also, we use the same key name as a variable ${name} within the Apache FreeMarker template file.
If we put these codes in a controller, we will have something similar as follows.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 | package com.turreta.headstart.notifier.controller; import freemarker.template.Configuration; import freemarker.template.TemplateException; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.http.ResponseEntity; import org.springframework.ui.freemarker.FreeMarkerTemplateUtils; import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.RestController; import java.io.IOException; import java.util.HashMap; import java.util.Map; @RestController public class MyRestController { @Autowired private Configuration fmConfiguration; @GetMapping("/generate-email") public ResponseEntity<String> generateEmail() throws IOException, TemplateException { Map<String, Object> model = new HashMap<>(); model.put("name", "turreta.com"); String email = FreeMarkerTemplateUtils.processTemplateIntoString( fmConfiguration.getTemplate("email-template.flth"), model); return ResponseEntity.ok().body(email); } } |
To help Apache FreeMarker read the template into memory, we use the getTemplate method from the FreeMarker Configuration class. When we access the endpoint, we will get the following output on the browser.
1 | Dear turreta.com |
We tested the codes using Spring Boot 2.5.6.