Open In App

Spring Boot – How Thymeleaf Works?

Last Updated : 09 Jan, 2024
Improve
Improve
Like Article
Like
Save
Share
Report

Thymeleaf is a Java library, and template engine used to parse and render the data produced by the application to template files – thus providing transformation. It is just like HTML but is provided with more attributes for working with rendered data. It allows caching of the parsed data/file to increase efficiency while in production. Types of templates it can process are – HTML, JAVASCRIPT, CSS, XML, TEXT, and RAW.

Template engines used with Spring-Boot:

  • Thymeleaf
  • FreeMarker
  • Mustache
  • Groovy
  • Java Server Pages

How Thymeleaf work with Spring-Boot?

  1. Thymeleaf follows a De-Coupled Architecture – It is unaware of any web framework.
  2. In the same way, it is unaware of Spring’s abstraction of the model and thus cannot handle the data that the controller places in the Model.
  3. When Spring-Boot’s autoconfiguration detects Thymeleaf in the classpath, it creates beans supporting Thymeleaf view for Spring MVC.
  4. It can work with request attributes of Servlet.
  5. Therefore, Spring copies the model data into request attributes that the Thymeleaf template can work with.

Simple life-cycle of Thymeleaf template

Client-Server-View-Life-Cycle-of-Thymeleaf-TemplateView-Server-Client-Life-Cycle-of-Thymeleaf-Template

To use Thymeleaf, add its dependency in the project build.

Maven – pom.xml

<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-thymeleaf</artifactId>
</dependency>

Gradle – build.gradle

compile group: 'org.springframework.boot', name: 'spring-boot-starter-thymeleaf'

Place the template files in the following directory:

/src/main/resources/templates/

Project Structure

1. Rendering a single model attribute

To render an attribute, use ‘th:text’ attribute in Thymeleaf Template

<p th:text="${attributeKey}"> attributeValue will be placed here </p>

Controller (TemplateController.java) file:

Java




package gfg;
 
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
 
@Controller
@RequestMapping("/")
public class TemplateController {
     
    @GetMapping("/template1")
    public String template(Model model) {
        String msg = "Welcome to Thymeleaf Template";
        // adding the attribute(key-value pair)
        model.addAttribute("message", msg);
        // returning the view name
        return "index";
    }
}


Template (index.html) file:

HTML




<!DOCTYPE html>
      xmlns:th="http://www.thymeleaf.org">
 <head>
 <title>GFG</title>
 </head>
 <body>
 <h1>Welcome to GeeksForGeeks...</h1>
 <div id="one">
     <h1 th:text="${message}">
       <span>message will print here</span>
     </h1>
 </div>
 </body>
 </html>


Output:

Output Screen Template1

2. Rendering a collection

To render a collection, use ‘th:each’ attributes in the Thymeleaf template

<p th:each="variable:${collectionName}"> 
<span th:text=${variable}> items iterated will be placed here </span>
</p>

Note: span tag will be iterated as much as the number of collection items.

Controller (TemplateController2.java) file:

Java




package gfg;
 
import java.util.ArrayList;
import java.util.List;
 
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
 
@Controller
@RequestMapping("/")
public class TemplateController2 {
     
    @GetMapping("/template2")
    public String template(Model model) {
        String message = "Top 5 Cloud Service Providers";
        // creating a collection
        List<String> list = new ArrayList<>();
        list.add("Amazon Web Services");
        list.add("Microsoft Azure");
        list.add("Google Cloud");
        list.add("Alibaba Cloud");
        list.add("IBM Cloud");
        model.addAttribute("message", message);
        // adding the collection attribute
        model.addAttribute("cloudProvider", list);
        return "index2";
    }
}


Template (index2.html) file:

HTML




<!DOCTYPE html>
 <head>
 <title>GFG2</title>
 </head>
 <body>
 <div id="one">
     <h2 th:text="${message}">
       <span>message will print here</span>
     </h2>
 </div >
 <div id="two" th:each="List:${cloudProvider}">
     <ul>
       <li>
        <span th:text=${List}>items will print here</span>
       </li>
     </ul>
 </div>
 </body>
 </html>


Output:

Output Screen Template2

3. Binding data to object

Pre-requisites: 

  • Object to which values will be bound must have ‘getter/setter’ methods for each field.
  • You can use the ‘Lombok’ library to generate these methods by ‘@Data’ annotation.

Add dependency of Lombok : Maven (pom.xml)

<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<optional>true</optional>
</dependency>

Using Thymeleaf, the input data is bound to the object using ‘th:object’ attribute

<form 
method="POST" th:object="${objectName}">
</form>

To map the input to a specific field of object use ‘th:field’ attribute

<input type="text" th:field="*{fieldName}" />

Controller (TemplateController3.java) file:

Java




package gfg;
 
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.ModelAttribute;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;
 
import gfg.os.OperatingSystem;
 
@Controller
@RequestMapping("/template3")
public class TemplateController3 {
     
    @GetMapping
    public String template(Model model) {
        model.addAttribute("ops", new OperatingSystem());
        return "index3";
    }
     
    @PostMapping
    public String template( @ModelAttribute("ops") OperatingSystem os , Model model) {
        model.addAttribute("message", os.getOS1()+" "+os.getOS2()+" "+os.getOS3());
        return "index";
    }
}


Class of the object to be bound (OperatingSystem.java) file:

Java




package gfg.os;
 
import lombok.Data;
 
@Data
public class OperatingSystem {
     
    public String OS1 ,OS2, OS3;
     
}


Template (index3.html) file:

HTML




<!DOCTYPE html>
 <head>
 <title>GFG3</title>
 </head>
 <body>
 <h1>Welcome to GeeksForGeeks...</h1>
 <form method="POST" th:object="${ops}">
  
        <div><label for="first">First OS</label></div>
        <input id="first"  type="text" th:field="*{OS1}" />
         
        <div><label for="second">Second OS</label></div>
        <input id="second"  type="text" th:field="*{OS2}" />
         
        <div><label for="third">Third OS</label></div>
        <input id="third"  type="text" th:field="*{OS3}" />
    
        <input type="submit" value="Send" />
    
 </form>
 </body>
 </html>


Output:

Output Screen Template3Output

Note: 

  • You can use other attributes of Thymeleaf as well.
  • The caching of the template is enabled by default.
  • You can turn off caching by specifying the following in the ‘application.properties’ file.

spring.thymeleaf.cache=false



Like Article
Suggest improvement
Previous
Next
Share your thoughts in the comments

Similar Reads