Thymeleaf Integration
About
Thymeleaf is a server-side Java template engine that is commonly used in web development, particularly in Java-based applications. It allows developers to create dynamic web pages by combining HTML templates with server-side data and logic.
Thymeleaf uses a syntax that is similar to HTML, making it relatively easy for developers to learn and use. Thymeleaf allows us to use the full power of Java within our templates, including conditional statements, loops, variables, and method invocations. This makes it flexible and powerful for handling complex rendering scenarios. Compared to client-side rendering frameworks, server-side rendering with Thymeleaf may have a performance overhead due to the need for server processing. If we have complex client-side logic, we may need to integrate Thymeleaf with a separate JavaScript framework.
In Thymeleaf, "th:" is a prefix used to indicate Thymeleaf-specific attributes within HTML templates. It is used to define and manipulate data in the template, control rendering behavior, and perform various other operations. The "th:" prefix stands for "Thymeleaf".
For example, some commonly used Thymeleaf attributes include:
"th:text": Sets the text value of an HTML element based on the provided expression.
"th:if" and "th:unless": Conditionally renders or omits an HTML element based on a specified condition.
"th:each": Iterates over a collection and renders HTML elements for each item in the collection.
Features of Thymeleaf
Server-side rendering: Thymeleaf enables server-side rendering of web pages, which means that the HTML templates are processed on the server before being sent to the client's browser. This allows for the dynamic generation of web content based on data from the server.
Data binding: Thymeleaf provides a way to bind data from the server to the HTML templates. It allows us to insert data dynamically into the templates, making it easy to display and manipulate server-side data on the client side.
Template layout: Thymeleaf supports the creation of reusable templates and layout components, which can be shared across multiple pages. This makes it easier to maintain consistent designs and improve code reusability.
Integration with Spring Framework: Thymeleaf integrates well with the Spring Framework, especially with the Spring Boot ecosystem. It is the default template engine for Spring Boot applications, providing seamless integration with other Spring features and libraries.
Overall, Thymeleaf is a powerful and popular choice for server-side Java web development, particularly in the Spring Boot ecosystem. Its simplicity, integration with Spring, and the ability to leverage the full power of Java within templates make it a compelling option for building dynamic web applications.
For more details, visit the official site - https://www.thymeleaf.org/index.html
Use Case
To build a login and dashboard using Thymeleaf and Spring Boot, combining the flexibility of server-side rendering with the security of database validation.
Setting up of MySQL using docker-compose method. Later on, we will connect this instance with MySQL Workbench and create user_credentials table along with test data.
docker-compose.yaml
version: "3.9"
# https://docs.docker.com/compose/compose-file/
services:
db-mysql:
container_name: db-mysql
image: mysql:8.0.29
ports:
- "3306:3306"
environment:
MYSQL_ROOT_PASSWORD: root
volumes:
- mysql-data:/var/lib/mysql
volumes:
mysql-data:
driver: local
networks:
default:
name: company_default
Start the mysql instance
docker-compose up db-mysql

Open the MySQL Workbench and execute below SQL commands.


Let's proceed with creating our Springboot project
Add the below dependencies in pom.xml file.
pom.xml
<!-- Spring Boot Starter Web -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<!-- Spring Boot Thymeleaf -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-thymeleaf</artifactId>
</dependency>
<!-- Spring Boot Starter Data JPA -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-jpa</artifactId>
</dependency>
<!-- MySQL Connector/J -->
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
</dependency>
<!-- Lombok -->
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<optional>true</optional>
</dependency>
<!-- Spring Dev Tools -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-devtools</artifactId>
<scope>runtime</scope>
<optional>true</optional>
</dependency>
application.yaml
server:
port: 4141
spring:
thymeleaf:
enabled: true
prefix: classpath:/templates/
suffix: .html
mode: HTML
resources:
static-locations: classpath:/static/
datasource:
url: jdbc:mysql://localhost:3306/users
username: root
password: root
driver-class-name: com.mysql.cj.jdbc.Driver
We will be using HTML templates available for use freely in the project. Download the login and dashboard template from the below sites
Login Template - https://colorlib.com/wp/template/login-form-v8/
Dashboard Template - https://html.design/?s=digit
Create a folder structure like below add the files in the respective folder

Later, we have the update the path in the html files like below as well as update the attribute to Thymeleaf attributes. For example below.


Also, I have added logic to the existing html and css file to highlight when user credential is incorrect.


Next, we can proceed with creating the required Java classes.
Main Application class
Application.java
package com.company.project;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.boot.SpringApplication;
@SpringBootApplication
public class Application {
public static void main(final String[] args) {
SpringApplication.run(Application.class, args);
}
}
Controller class with 2 methods. One method to show login page and other method which gets into action after submitting the login form by entering the credentials.
LoginController.java
package com.company.project.api;
import com.company.project.repository.UserRepository;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.servlet.ModelAndView;
import lombok.RequiredArgsConstructor;
@RequiredArgsConstructor
@RestController
@RequestMapping("/page")
public class LoginController {
private final UserRepository userRepository;
@GetMapping("/login")
public ModelAndView showLoginPage() {
return new ModelAndView("login/index");
}
@PostMapping("/login")
public ModelAndView processLoginForm(@RequestParam("username") String username,
@RequestParam("password") String password) {
ModelAndView modelAndView;
boolean userExists = userRepository.existsByUsernameAndPassword(username, password);
if (userExists) {
modelAndView = new ModelAndView("dashboard/index");
} else {
modelAndView = new ModelAndView("login/index");
modelAndView.addObject("errorMessage", "Invalid username or password.");
}
return modelAndView;
}
}
Of course, we have make model class for the user_credentials as well as repository class.
UserCredentials.java
package com.company.project.model;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.Table;
import lombok.Data;
@Data
@Entity
@Table(name = "user_credentials")
public class UserCredentials {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
private String username;
private String password;
private String email;
}
UserRepository.java
package com.company.project.repository;
import org.springframework.data.jpa.repository.JpaRepository;
import com.company.project.model.UserCredentials;
public interface UserRepository extends JpaRepository<UserCredentials, Long> {
boolean existsByUsernameAndPassword(String username, String password);
}
Overall, project structure is as below

It's time to run the application and see it in action.

Navigate to this url - http://localhost:4141/page/login

Case 1: Enter incorrect credential


Case 2: Enter correct credential

​

Attached below are the files for reference.
Last updated