Introduction
In this chapter, we will build a web application using Spring Boot and Thymeleaf. We will create a Student Management System project to demonstrate the integration of Thymeleaf with Spring Boot, and we will explain Spring Boot auto-configuration for Thymeleaf. This chapter will guide you through setting up the project, configuring Thymeleaf, and building the web interface for managing students.
Table of Contents
- Introduction
- Create and Setup Spring Boot Project in IntelliJ IDEA
- Configure H2 Database
- Create Student Entity
- Create Student Repository
- Create Service Layer
- StudentService
- StudentServiceImpl
- Create StudentController
- Spring Boot Thymeleaf Integration
- Spring Boot Auto-Configuration for Thymeleaf
- Create Thymeleaf Templates
- Test the Application
- Conclusion
Create and Setup Spring Boot Project in IntelliJ IDEA
Create a New Spring Boot Project
- Open Spring Initializr:
- Go to Spring Initializr in your web browser.
- Configure Project Metadata:
- Project: Maven Project
- Language: Java
- Spring Boot: 3.2.0
- Group:
com.example - Artifact:
student-management - Name:
student-management - Description:
Student Management System - Package name:
com.example.studentmanagement - Packaging: Jar
- Java: 17 (or the latest version available)
- Add Dependencies:
- Spring Web
- Spring Data JPA
- H2 Database
- Thymeleaf
- Generate the Project:
- Click “Generate” to download the project as a ZIP file.
- Import Project into IntelliJ IDEA:
- Open IntelliJ IDEA.
- Click on “Open” and navigate to the downloaded ZIP file.
- Extract the ZIP file and import the project.
Explanation
- Spring Initializr: A web-based tool provided by Spring to bootstrap a new Spring Boot project with dependencies and configurations.
- Group and Artifact: Define the project’s Maven coordinates.
- Dependencies: Adding dependencies ensures that the necessary libraries are included in the project for web development, JPA, H2 database connectivity, and Thymeleaf integration.
Configure H2 Database
Update application.properties
- Open
application.properties:- Navigate to
src/main/resources/application.properties.
- Navigate to
- Add H2 Database Configuration:
- Add the following properties to configure the H2 database connection:
spring.datasource.url=jdbc:h2:mem:studentdb
spring.datasource.driverClassName=org.h2.Driver
spring.datasource.username=sa
spring.datasource.password=password
spring.jpa.hibernate.ddl-auto=update
spring.h2.console.enabled=true
spring.h2.console.path=/h2-console
Explanation
spring.datasource.url: The JDBC URL to connect to the H2 database in memory.spring.datasource.driverClassName: The driver class name for H2 database.spring.datasource.username: The username to connect to the H2 database.spring.datasource.password: The password to connect to the H2 database.spring.jpa.hibernate.ddl-auto: Specifies the Hibernate DDL mode. Setting it toupdateautomatically updates the database schema based on the entity mappings.spring.h2.console.enabled: Enables the H2 database console for easy access to the database through a web browser.spring.h2.console.path: Specifies the path to access the H2 console.
Create Student Entity
Create the Student Class
- Create a New Package:
- In the
src/main/java/com/example/studentmanagementdirectory, create a new package namedmodel.
- In the
- Create the
StudentClass:- Inside the
modelpackage, create a new class namedStudent. - Add the following code to the
Studentclass:
- Inside the
package com.example.studentmanagement.model;
import jakarta.persistence.Entity;
import jakarta.persistence.GeneratedValue;
import jakarta.persistence.GenerationType;
import jakarta.persistence.Id;
@Entity
public class Student {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
private String firstName;
private String lastName;
private String email;
// Constructors
public Student() {}
public Student(String firstName, String lastName, String email) {
this.firstName = firstName;
this.lastName = lastName;
this.email = email;
}
// Getters and Setters
public Long getId() {
return id;
}
public void setId(Long id) {
this.id = id;
}
public String getFirstName() {
return firstName;
}
public void setFirstName(String firstName) {
this.firstName = firstName;
}
public String getLastName() {
return lastName;
}
public void setLastName(String lastName) {
this.lastName = lastName;
}
public String getEmail() {
return email;
}
public void setEmail(String email) {
this.email = email;
}
}
Explanation
@Entity: Specifies that the class is an entity and is mapped to a database table.@Id: Specifies the primary key of the entity.@GeneratedValue: Specifies how the primary key should be generated.GenerationType.IDENTITYindicates that the primary key is auto-incremented.
Create Student Repository
Create the StudentRepository Interface
- Create a New Package:
- In the
src/main/java/com/example/studentmanagementdirectory, create a new package namedrepository.
- In the
- Create the
StudentRepositoryInterface:- Inside the
repositorypackage, create a new interface namedStudentRepository. - Add the following code to the
StudentRepositoryinterface:
- Inside the
package com.example.studentmanagement.repository;
import com.example.studentmanagement.model.Student;
import org.springframework.data.jpa.repository.JpaRepository;
public interface StudentRepository extends JpaRepository<Student, Long> {
}
Explanation
JpaRepository: TheStudentRepositoryinterface extendsJpaRepository, providing CRUD operations for theStudententity. TheJpaRepositoryinterface includes methods likesave(),findById(),findAll(),deleteById(), etc.- Generics: The
JpaRepositoryinterface takes two parameters: the entity type (Student) and the type of its primary key (Long).
Create Service Layer
Create StudentService Interface
- Create a New Package:
- In the
src/main/java/com/example/studentmanagementdirectory, create a new package namedservice.
- In the
- Create the
StudentServiceInterface:- Inside the
servicepackage, create a new interface namedStudentService. - Add the following code to the
StudentServiceinterface:
- Inside the
package com.example.studentmanagement.service;
import com.example.studentmanagement.model.Student;
import java.util.List;
public interface StudentService {
Student saveStudent(Student student);
Student getStudentById(Long id);
List<Student> getAllStudents();
Student updateStudent(Long id, Student studentDetails);
void deleteStudent(Long id);
}
Explanation
- Service Interface: Defines the contract for the service layer. It includes methods for saving, retrieving, updating, and deleting students.
Create StudentServiceImpl Class
- Create the
StudentServiceImplClass:- Inside the
servicepackage, create a new class namedStudentServiceImpl. - Add the following code to the
StudentServiceImplclass:
- Inside the
package com.example.studentmanagement.service;
import com.example.studentmanagement.model.Student;
import com.example.studentmanagement.repository.StudentRepository;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import java.util.List;
@Service
public class StudentServiceImpl implements StudentService {
@Autowired
private StudentRepository studentRepository;
@Override
public Student saveStudent(Student student) {
return studentRepository.save(student);
}
@Override
public Student getStudentById(Long id) {
return studentRepository.findById(id)
.orElseThrow(() -> new RuntimeException("Student not found with id: " + id));
}
@Override
public List<Student> getAllStudents() {
return studentRepository.findAll();
}
@Override
public Student updateStudent(Long id, Student studentDetails) {
Student student = studentRepository.findById(id)
.orElseThrow(() -> new RuntimeException("Student not found with id: " + id));
student.setFirstName(studentDetails.getFirstName());
student.setLastName(studentDetails.getLastName());
student.setEmail(studentDetails.getEmail());
return studentRepository.save(student);
}
@Override
public void deleteStudent(Long id) {
Student student = studentRepository.findById(id)
.orElseThrow(() -> new RuntimeException("Student not found with id: " + id));
studentRepository.delete(student);
}
}
Explanation
@Service: Indicates that this class is a service component in the Spring context.StudentRepository: TheStudentRepositoryinstance is injected into the service class to interact with the database.
- Exception Handling: The
getStudentById,updateStudent, anddeleteStudentmethods throw aRuntimeExceptionif the student is not found.
Create StudentController
Create the StudentController Class
- Create a New Package:
- In the
src/main/java/com/example/studentmanagementdirectory, create a new package namedcontroller.
- In the
- Create the
StudentControllerClass:- Inside the
controllerpackage, create a new class namedStudentController. - Add the following code to the
StudentControllerclass:
- Inside the
package com.example.studentmanagement.controller;
import com.example.studentmanagement.model.Student;
import com.example.studentmanagement.service.StudentService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.*;
import java.util.List;
@Controller
@RequestMapping("/students")
public class StudentController {
@Autowired
private StudentService studentService;
@GetMapping
public String listStudents(Model model) {
List<Student> students = studentService.getAllStudents();
model.addAttribute("students", students);
return "students";
}
@GetMapping("/new")
public String createStudentForm(Model model) {
Student student = new Student();
model.addAttribute("student", student);
return "create_student";
}
@PostMapping
public String saveStudent(@ModelAttribute("student") Student student) {
studentService.saveStudent(student);
return "redirect:/students";
}
@GetMapping("/edit/{id}")
public String editStudentForm(@PathVariable Long id, Model model) {
Student student = studentService.getStudentById(id);
model.addAttribute("student", student);
return "edit_student";
}
@PostMapping("/{id}")
public String updateStudent(@PathVariable Long id, @ModelAttribute("student") Student student, Model model) {
Student existingStudent = studentService.getStudentById(id);
existingStudent.setFirstName(student.getFirstName());
existingStudent.setLastName(student.getLastName());
existingStudent.setEmail(student.getEmail());
studentService.updateStudent(id, existingStudent);
return "redirect:/students";
}
@GetMapping("/delete/{id}")
public String deleteStudent(@PathVariable Long id) {
studentService.deleteStudent(id);
return "redirect:/students";
}
}
Explanation
@Controller: Indicates that this class is a Spring MVC controller.@RequestMapping("/students"): Maps HTTP requests to/studentsto methods in this controller.- Model: Used to pass data between the controller and the view.
listStudents: Handles HTTP GET requests to display the list of students.createStudentForm: Handles HTTP GET requests to display the form for creating a new student.saveStudent: Handles HTTP POST requests to save a new student.editStudentForm: Handles HTTP GET requests to display the form for editing a student.updateStudent: Handles HTTP POST requests to update an existing student.deleteStudent: Handles HTTP GET requests to delete a student.
Spring Boot Thymeleaf Integration
Explanation
Spring Boot integrates seamlessly with Thymeleaf, a modern server-side Java template engine for web and standalone environments. Thymeleaf allows you to create dynamic web pages using HTML templates, which are easy to design and understand. Spring Boot auto-configures Thymeleaf with minimal setup, allowing you to focus on building the application logic.
Spring Boot Auto-Configuration for Thymeleaf
Explanation
Spring Boot provides auto-configuration for Thymeleaf through the spring-boot-starter-thymeleaf dependency. This auto-configuration sets up the necessary beans and templates to use Thymeleaf in a Spring Boot application. By default, Spring Boot looks for Thymeleaf templates in the src/main/resources/templates directory and configures the template resolver, template engine, and view resolver automatically.
Create Thymeleaf Templates
Create Templates Directory
- Create a New Directory:
- In the
src/main/resourcesdirectory, create a new directory namedtemplates.
- In the
Create students.html Template
- Create the
students.htmlFile:- Inside the
templatesdirectory, create a new file namedstudents.html. - Add the following code to the
students.htmlfile:
- Inside the
<!DOCTYPE html>
<html xmlns:th="http://www.thymeleaf.org">
<head>
<meta charset="UTF-8">
<title>Student List</title>
</head>
<body>
<h1>Students</h1>
<table>
<thead>
<tr>
<th>ID</th>
<th>First Name</th>
<th>Last Name</th>
<th>Email</th>
<th>Actions</th>
</tr>
</thead>
<tbody>
<tr th:each="student : ${students}">
<td th:text="${student.id}"></td>
<td th:text="${student.firstName}"></td>
<td th:text="${student.lastName}"></td>
<td th:text="${student.email}"></td>
<td>
<a th:href="@{/students/edit/{id}(id=${student.id})}">Edit</a>
<a th:href="@{/students/delete/{id}(id=${student.id})}">Delete</a>
</td>
</tr>
</tbody>
</table>
<a href="/students/new">Add New Student</a>
</body>
</html>
Explanation
th:each: Iterates over the list of students and binds each student to the variablestudent.th:text: Replaces the text content of the HTML element with the value of the specified expression.th:href: Replaces the href attribute of the anchor tag with the specified URL.
Create create_student.html Template
- Create the
create_student.htmlFile:- Inside the
templatesdirectory, create a new file namedcreate_student.html. - Add the following code to the
create_student.htmlfile:
- Inside the
<!DOCTYPE html>
<html xmlns:th="http://www.thymeleaf.org">
<head>
<meta charset="UTF-8">
<title>Create Student</title>
</head>
<body>
<h1>Create Student</h1>
<form th:action="@{/students}" th:object="${student}" method="post">
<label for="firstName">First Name:</label>
<input type="text" id="firstName" th:field="*{firstName}" required>
<br>
<label for="lastName">Last Name:</label>
<input type="text" id="lastName" th:field="*{lastName}" required>
<br>
<label for="email">Email:</label>
<input type="email" id="email" th:field="*{email}" required>
<br>
<button type="submit">Save</button>
</form>
<a href="/students">Back to Student List</a>
</body>
</html>
Explanation
th:action: Sets the form action URL.th:object: Binds the form to the specified object.th:field: Binds the input field to the specified property of the object.
Create edit_student.html Template
- Create the
edit_student.htmlFile:- Inside the
templatesdirectory, create a new file namededit_student.html. - Add the following code to the
edit_student.htmlfile:
- Inside the
<!DOCTYPE html>
<html xmlns:th="http://www.thymeleaf.org">
<head>
<meta charset="UTF-8">
<title>Edit Student</title>
</head>
<body>
<h1>Edit Student</h1>
<form th:action="@{/students/{id}(id=${student.id})}" th:object="${student}" method="post">
<label for="firstName">First Name:</label>
<input type="text" id="firstName" th:field="*{firstName}" required>
<br>
<label for="lastName">Last Name:</label>
<input type="text" id="lastName" th:field="*{lastName}" required>
<br>
<label for="email">Email:</label>
<input type="email" id="email" th:field="*{email}" required>
<br>
<button type="submit">Save</button>
</form>
<a href="/students">Back to Student List</a>
</body>
</html>
Explanation
th:action: Sets the form action URL.th:object: Binds the form to the specified object.th:field: Binds the input field to the specified property of the object.
Test the Application
Run the Application
- Run the Application:
- In IntelliJ IDEA, run the
StudentManagementApplicationclass.
- In IntelliJ IDEA, run the
Access the
Application
- Open Web Browser:
- Open a web browser and go to
http://localhost:8080/students.
- Open a web browser and go to
- Verify the Application:
- Verify that you can view the list of students, create a new student, edit an existing student, and delete a student.
Conclusion
In this chapter, we built a web application using Spring Boot and Thymeleaf. We created a Student Management System project, configured the H2 database, created entities and repositories, integrated Thymeleaf with Spring Boot, and built the web interface for managing students. Each step was explained in detail to help you understand the process of building a web application with Spring Boot and Thymeleaf.