Sunday, September 22, 2024
Google search engine
HomeLanguagesJavaSpring Boot – How Thymeleaf Works?

Spring Boot – How Thymeleaf Works?

Thymeleaf is a Java library, 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 at production. Types of templates it can process are – HTML, JAVASCRIPT, CSS, XML, TEXT, RAW.

Template engines used with Spring-Boot:

  1. Thymeleaf
  2. FreeMarker
  3. Mustache
  4. Groovy
  5. Java Server Pages

How Thymeleaf works 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 the Spring’s abstraction of model and thus cannot handle the data that the controller places in 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-Template

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

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 (Maven)

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:

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:

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:

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

RELATED ARTICLES

Most Popular

Recent Comments