Thymeleaf
This blog will help us to get complete understanding on Spring Boot Thymeleaf concepts with downloadable code zip package at the end of the blog.
Thymeleaf is a Java based library which helps us to create web application.
Thymeleaf templates allow us create dynamic Spring boot web application.
Thymeleaf consumption in Spring Boot is almost similar to JSP in advanced Java.
Below maven dependency is required to use Thymeleaf in Spring Boot application:
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-thymeleaf</artifactId>
</dependency>
Include below line as part of every template to consume Thymeleaf on every html page.
<html xmlns:th="https://thymeleaf.org">
Follow below steps to create Spring Boot project using Spring Initializr:
- Lets create a project using Spring Initializr using link
- Fill Group and Artifact detail as com.javadoubts and practice respectively.
- Add dependencies as Spring Web and Spring boot actuator as mentioned in below screenshot.
- information as mentioned in below screenshot. Add dependencies as Spring Web, Spring Boot Actuator and Thymeleaf .
- Click on Generate button will download a zip file inside download folder.
Follow below code hierarchy to create spring boot application.
Use Case:
As part of this blog, we will be submitting a form and collecting a user name, age and date. Same information will get print on next page after successful submission.
This use case will provide deep understanding of Thymeleaf attributes such as th:action, th:object, th:field, th:assert, th:text, th:switch, th:case, th:if, th:unless, data-th-each and data-th-text.
Create User.java bean class having name, age and date as fields.
package com.javadoubts.practice;
import java.util.Date;
import org.springframework.format.annotation.DateTimeFormat;
import org.springframework.format.annotation.NumberFormat;
public class User {
private String name;
@NumberFormat
private int age;
@DateTimeFormat(pattern = "yyyy-MM-dd")
private Date date;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
public Date getDate() {
return date;
}
public void setDate(Date date) {
this.date = date;
}
public User() {
super();
}
public User(String name, int age, Date date) {
super();
this.name = name;
this.age = age;
this.date = date;
}
}
Note:
1. It is important to annotate age as @NumberFormat to avoid an exception on form submission as it is number type with.
2. It is also important to annotate date @DateTimeFormat(pattern = “yyyy-MM-dd”) to avoid an exception on form submission as it is date type.
Create UserController.java with below content:
package com.javadoubts.practice;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.ModelAttribute;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
@Controller
public class UserController {
@RequestMapping(value="/user", method=RequestMethod.GET)
public String index(Model model)
{
model.addAttribute("user", new User());
return"index";
}
@RequestMapping(value="/user", method=RequestMethod.POST)
public String getUser(@ModelAttribute User user, Model model) {
// Set title and username in model as an attribute.
model.addAttribute("title", "This is user page !!!");
model.addAttribute("username", "John");
// Create list of users
List<User> users = new ArrayList();
users.add(new User("John", 30, new Date()));
users.add(new User("Harry", 33, new Date()));
users.add(new User(user.getName(), user.getAge(), user.getDate()));
// Set list of users in model as an attribute.
model.addAttribute("users", users);
// Set user in model as an attribute.
model.addAttribute("user", user);
return "user";
}
}
@RestController annotation used to created RESTful web services which can be accessed using http methods like GET, POST, etc. and it is the combination of @Controller and @ResponseBody.
@RequestMapping used to map HTTP GET and POST request. It mainly used to fetch/send data to server.
Create index.html file to create a form
<!DOCTYPE html>
<html lang="en" xmlns:th="http://www.thymeleaf.org">
<head>
<title>Practice Thymeleaf</title>
</head>
<body>
<h2>Enter User Information !!!</h2>
<!--
On page load, th:object will get map to empty User
with the help of model.addAttribute("user", new User());
-->
<form action="#" th:action="@{/user}" th:object="${user}" method="post">
<div>
<label>Name</label>
<!-- Map name field to user object -->
<input type="text" th:field="*{name}">
</div>
<div>
<label>Age</label>
<!-- Map age field to user object -->
<input type="number" th:field="*{age}">
</div>
<div>
<label>Birth</label>
<!-- Map date field to user object -->
<input type="date" th:field="*{date}">
</div>
<input type="submit" value="Submit">
</form>
</body>
</html>
Create user.html file to collect and print submit data.
<!DOCTYPE html>
<html lang="en" xmlns:th="http://www.thymeleaf.org">
<head>
<title>Practice Thymeleaf</title>
</head>
<body>
<!-- print user name if it is not empty -->
<div>User Name: <span th:text="${user.name}"
th:assert="${!#strings.isEmpty(user.name)}"></span></div>
<br/>
<!-- Switch case -->
<div th:switch="${user.name}">
<span th:case="'Tom'">This is Tom Switch Case</span>
<span th:case="'Harry'">This is Harry</span>
</div>
<br/>
<!-- if condition -->
<div>
<span th:if="${user.name} == 'Tom'">This is Tom if condition</span>
</div>
<br/>
<!-- else condition -->
<div>
<span th:unless="${user.name} != 'Tom'">Else condition for username not equal to Tom</span>
</div>
<br/>
<table>
<caption>Users</caption>
<thead>
<td>Name</td>
<td>Age</td>
<td>Date</td>
</thead>
<!-- Traverse through users list object -->
<tr data-th-each="user : ${users}">
<td data-th-text="${user.name}"></td>
<td data-th-text="${user.age}"></td>
<td data-th-text="${#dates.format(user.date, 'dd-MMM-yyyy')}"></td>
</tr>
</table>
</body>
</html>
Load Style
Place style.css inside static folder as shown below. Load style.css with the help of <link> tag, th:href and rel attributes.
Imran Khan, Adobe Community Advisor, AEM certified developer and Java Geek, is an experienced AEM developer with over 11 years of expertise in designing and implementing robust web applications. He leverages Adobe Experience Manager, Analytics, and Target to create dynamic digital experiences. Imran possesses extensive expertise in J2EE, Sightly, Struts 2.0, Spring, Hibernate, JPA, React, HTML, jQuery, and JavaScript.