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 toupdate
automatically 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/studentmanagement
directory, create a new package namedmodel
.
- In the
- Create the
Student
Class:- Inside the
model
package, create a new class namedStudent
. - Add the following code to the
Student
class:
- 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.IDENTITY
indicates 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/studentmanagement
directory, create a new package namedrepository
.
- In the
- Create the
StudentRepository
Interface:- Inside the
repository
package, create a new interface namedStudentRepository
. - Add the following code to the
StudentRepository
interface:
- 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
: TheStudentRepository
interface extendsJpaRepository
, providing CRUD operations for theStudent
entity. TheJpaRepository
interface includes methods likesave()
,findById()
,findAll()
,deleteById()
, etc.- Generics: The
JpaRepository
interface 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/studentmanagement
directory, create a new package namedservice
.
- In the
- Create the
StudentService
Interface:- Inside the
service
package, create a new interface namedStudentService
. - Add the following code to the
StudentService
interface:
- 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
StudentServiceImpl
Class:- Inside the
service
package, create a new class namedStudentServiceImpl
. - Add the following code to the
StudentServiceImpl
class:
- 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
: TheStudentRepository
instance is injected into the service class to interact with the database.
- Exception Handling: The
getStudentById
,updateStudent
, anddeleteStudent
methods throw aRuntimeException
if the student is not found.
Create StudentController
Create the StudentController
Class
- Create a New Package:
- In the
src/main/java/com/example/studentmanagement
directory, create a new package namedcontroller
.
- In the
- Create the
StudentController
Class:- Inside the
controller
package, create a new class namedStudentController
. - Add the following code to the
StudentController
class:
- 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/students
to 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/resources
directory, create a new directory namedtemplates
.
- In the
Create students.html
Template
- Create the
students.html
File:- Inside the
templates
directory, create a new file namedstudents.html
. - Add the following code to the
students.html
file:
- 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.html
File:- Inside the
templates
directory, create a new file namedcreate_student.html
. - Add the following code to the
create_student.html
file:
- 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.html
File:- Inside the
templates
directory, create a new file namededit_student.html
. - Add the following code to the
edit_student.html
file:
- 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
StudentManagementApplication
class.
- 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.