Hi, thank you for visiting here. Have a nice day. 👋
In this tutorial, you'll learn how to create a simple web application with Spring Boot. This is very useful for beginners to learn Spring Boot.
I will also provide my code.
We use Java 11.
Spring Boot is an open source Java-based framework.
We use MySQL as a database service. If you haven't downloaded it yet, please download it.
Thymeleaf is a modern server-side Java template engine for both web and standalone environments.
We use an Eclipse IDE. You can use your favorite one.
Spring Initializr pulls in all the dependencies you need for your application and does most of the setup for you. Please visit the Spring Initializr and generate a new project as follows. (If your IDE has the Spring Initializr integration, you can complete this process from your IDE.)
Project: Maven Project
Language: Java
Spring Boot: 2.52
Project Metadata
Group: com.example
Artifact: employee-management-system
Name: employee-management-system
Description: Demo project for Spring Boot Web App
Package name: com.example.employee-management-system
Packaging: Jar
Java: 11
Dependencies: Spring Web, Spring Data JPA, Thymeleaf, Spring Boot DevTools, MySQL Driver
Then, import the project which you generate in Spring Initializr into Eclipse workspace. If you don't know how to do that, refer to this article.
application.properties
fileSpring Boot gives you H2
as the default database. When you want to use any other database (we use MySQL.), you need to define the attributes in the application.properties
file.
Please open the src/main/resources/application.properties
file and enter the attributes with the following code.
# DATASOURCE (DataSourceAutoConfiguration & DataSourceProperties)
spring.datasource.url=your database url
spring.datasource.username=your database username
spring.datasource.password=your database password
# Hibernate ddl auto (create, create-drop, validate, update)
spring.jpa.hibernate.ddl-auto = update
Generally, the attribute of spring.datasource.url
looks like this: jdbc:mysql://localhost:3306/employee-management-system
About spring.jpa.hibernate.ddl-auto
see the Hibernate documentation for details.
Next, create controller package
, domain package
, repository package
and service package
at src/main/java/com/example/com.example.employee-management-system
. We're gonna make files under these packages later.
Create the Class called Employee
at the domain package
with the following code.
*Comments in the code might be helpful for you to understand what's going on in Spring Boot application
package com.example.employeemanagementsystem.domain;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
@Entity // This tells Hibernate to create a table of this class
public class Employee {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
// By @GeneratedValue, JPA makes a unique key automatically and applies the key to the field having @Id
private long id;
private String firstName;
private String lastName;
private String email;
public Employee() {
}
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;
}
}
Create the Class called EmployeeRepository
at the repository package
with the following code.
*Comments in the code might be helpful for you to understand what's going on in Spring Boot application
package com.example.employeemanagementsystem.repository;
import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.stereotype.Repository;
import com.satoruakiyama.employeemanagementsystem.domain.Employee;
@Repository
public interface EmployeeRepository extends JpaRepository<Employee, Long> {
// This will be AUTO IMPLEMENTED by Spring into a Bean
}
JpaRepository is a JPA specific extension of Repository. It is useful for basic CRUD operations and also API for pagination and sorting. You can see details here.
Create the Class called EmployeeService
at the service package
with the following code.
*Comments in the code might be helpful for you to understand what's going on in Spring Boot application
package com.example.employeemanagementsystem.service;
import java.util.List;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import com.satoruakiyama.employeemanagementsystem.domain.Employee;
import com.satoruakiyama.employeemanagementsystem.repository.EmployeeRepository;
@Service // This means that this class is a service
public class EmployeeService {
@Autowired
// to get the bean which is auto-generated by Spring
// We will use it to handle the data
EmployeeRepository employeeRepository;
// get all employees
public List<Employee> getAllEmployees() {
// find all employees data, then return it
return employeeRepository.findAll();
}
// save an employee
public void saveEmployee(Employee emp) {
// save employee data to database
employeeRepository.save(emp);
}
// get employee by id
public Employee getEmployeeById(Long id) {
// find an employee by id
Employee emp = employeeRepository.getById(id);
// if there is not an employee who has the id, throw the error.
if (emp == null) {
throw new RuntimeException("Employee not found");
}
return emp;
}
// delete employee by id
public String deleteEmployeeById(Long id) {
// find an employee by id
Employee emp = employeeRepository.getById(id);
// if there is not an employee who has the id, throw the error.
if (emp == null) {
throw new RuntimeException("Employee not found");
}
// delete an employee who has the id from the database
employeeRepository.deleteById(id);
return "Deleted: " + emp.getFirstName() + " " + emp.getLastName();
}
}
Create the Class called EmployeeController
at the controller package
with the following code.
*Comments in the code might be helpful for you to understand what's going on in Spring Boot application
package com.example.employeemanagementsystem.controller;
import org.springframework.beans.factory.annotation.Autowired;
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.PathVariable;
import org.springframework.web.bind.annotation.PostMapping;
import com.satoruakiyama.employeemanagementsystem.domain.Employee;
import com.satoruakiyama.employeemanagementsystem.service.EmployeeService;
@Controller // This means that this class is a Controller
public class EmployeeController {
@Autowired
// This means to get the bean which is auto-generated by Spring
// We will use an employeeService for each
EmployeeService employeeService;
// display list of employees
@GetMapping("/")
// This means that this method will be executed when user sends GET Requests to "/"
// In our case, "http://localhost:8080/"
public String viewHomePage(Model model) {
// We can use this attribute "listEmployees" to perform server-side rendering of the HTML with using Thymeleaf.
// We set all employees data to "listEmployees"
model.addAttribute("listEmployees", employeeService.getAllEmployees());
// shows the index.html template:
return "index";
}
// showNewEmployeeForm
@GetMapping("/showNewEmployeeForm")
// This means that this method will be executed when user sends GET Requests to "/showNewEmployeeForm"
// In our case, "http://localhost:8080/showNewEmployeeForm"
public String showNewEmployeeForm(Model model) {
Employee employee = new Employee();
// We can use this attribute "employee" to perform server-side rendering of the HTML with using Thymeleaf.
model.addAttribute("employee", employee);
// shows the new_employee.html template:
return "new_employee";
}
// add an employee
@PostMapping("/saveEmployee")
// This means that this method will be executed when user sends POST Requests to "/saveEmployee"
// In our case, "http://localhost:8080/saveEmployee"
public String saveEmployee(@ModelAttribute("employee") Employee employee) {
// @ModelAttribute binds the object called "employee" of request body from the POST request into the employee parameter of the saveEmployee() method.
employeeService.saveEmployee(employee);
// after save the employee data to database, redirect to "/"
return "redirect:/";
}
// show update form
@GetMapping("/showFormForUpdate/{id}")
// This means that this method will be executed when user sends GET Requests to "/showFormForUpdate/{employee's id}"
// In our case, "http://localhost:8080/showFormForUpdate/{employee's id}"
public String showUpdateForm(@PathVariable Long id, Model model) {
// @PathVariable binds the {id} which the path of GET request contains into the id parameter of showUpdateForm() method.
Employee employee = employeeService.getEmployeeById(id);
// We can use this attribute "employee" to perform server-side rendering of the HTML with using Thymeleaf.
// We set employee data to "employee"
model.addAttribute("employee", employee);
// shows the update_employee.html template:
return "update_employee";
}
// delete the employee by id
@GetMapping("/delete/{id}")
// This means that this method will be executed when user sends GET Requests to "/delete/{employee's id}"
// In our case, "http://localhost:8080/delete/{employee's id}"
public String deleteEmployeeById(@PathVariable Long id, Model model) {
employeeService.deleteEmployeeById(id);
// after delete the employee data from database, redirect to "/"
return "redirect:/";
}
}
Next we are going to create HTML template files by using Thymeleaf. We use Materialize css which is a modern responsive front-end framework based on Material Design for styling our application.
Please create index.html
, new_employee.html
, update_employee.html
at src/main/resources/templates
with the following code.
*Comments in the code might be helpful for you to understand what's going on.
・index.html
<!DOCTYPE html>
<!-- This is for using Thymeleaf -->
<html xmlns:th="http://www.thymeleaf.org">
<head>
<meta charset="UTF-8">
<title>Employee Management System</title>
<!-- Compiled and minified CSS -->
<link rel="stylesheet"
href="https://cdnjs.cloudflare.com/ajax/libs/materialize/1.0.0/css/materialize.min.css">
<!-- Compiled and minified JavaScript -->
<script
src="https://cdnjs.cloudflare.com/ajax/libs/materialize/1.0.0/js/materialize.min.js"></script>
</head>
<body style="max-width: 960px; margin: 16px auto; padding: 16px">
<h3>Employee List</h3>
<!-- The link which sends GET request to "/showNewEmployeeForm" -->
<a th:href="@{/showNewEmployeeForm}"
class="waves-effect waves-light btn">Add new employee</a>
<div align="center" style="margin-top: 20px">
<table class="responsive-table striped highlight centered">
<thead>
<tr>
<th>First Name</th>
<th>Last Name</th>
<th>Email</th>
<th>Actions</th>
</tr>
</thead>
<tbody>
<!-- You can acccess model attributes which are added in a Controller(EmployeeController.java) with ${attributeName}.
In this case, it is "${listEmployees}".
To show all employees data in this table, you need to use "th:each" in the thymeleaf template and iterate the employee of listEmployees -->
<tr th:each="employee: ${listEmployees}">
<td th:text="${employee.firstName}"></td>
<td th:text="${employee.lastName}"></td>
<td th:text="${employee.email}"></td>
<td>
<!-- The link which sends GET request to "/showFormForUpdate/{id}" (id is employee.id) -->
<a th:href="@{/showFormForUpdate/{id}(id=${employee.id})}"
class="waves-effect waves-light btn">Update</a>
</td>
<td>
<!-- The link which sends GET request to "/delete/{id}" (id is employee.id) -->
<a th:href="@{/delete/{id}(id=${employee.id})}"
class="waves-effect waves-light btn red litghten-2">Delete</a>
</td>
</tr>
</tbody>
</table>
</div>
</body>
</html>
・new_employee.html
<!DOCTYPE html>
<!-- This is for using Thymeleaf -->
<html xmlns:th="http://www.thymeleaf.org">
<head>
<meta charset="UTF-8">
<title>Employee Management System</title>
<!-- Compiled and minified CSS -->
<link rel="stylesheet"
href="https://cdnjs.cloudflare.com/ajax/libs/materialize/1.0.0/css/materialize.min.css">
<!-- Compiled and minified JavaScript -->
<script
src="https://cdnjs.cloudflare.com/ajax/libs/materialize/1.0.0/js/materialize.min.js"></script>
</head>
<body style="max-width: 960px; margin: 16px auto; padding: 16px">
<h3>Add New Employee</h3>
<!-- The th:action="@{/saveEmployee}" expression directs the form to POST to the /saveEmployee endpoint.
The th:object="${employee}" expression declares the model object to use for collecting the form data.
The three form fields, expressed with th:field, correspond to the fields in the Employee object. -->
<form th:action="@{/saveEmployee}" th:object="${employee}" method="post">
<div class="row">
<div class="input-field col s6">
<input id="first_name" type="text" class="validate"
th:field="*{firstName}"> <label for="first_name">First
Name</label>
</div>
<div class="input-field col s6">
<input id="last_name" type="text" class="validate"
th:field="*{lastName}"> <label for="last_name">Last
Name</label>
</div>
</div>
<div class="row">
<div class="input-field col s6">
<input id="email" type="email" class="validate" th:field="*{email}">
<label for="email">Email</label>
</div>
</div>
<button type="submit" class="waves-effect waves-light btn">Add
Employee</button>
</form>
<br>
<!-- The link which sends GET request to "/" -->
<a th:href="@{/}"
class="blue-text">Back</a>
</body>
</html>
・update_employee.html
<!DOCTYPE html>
<!-- This is for using Thymeleaf -->
<html xmlns:th="http://www.thymeleaf.org">
<head>
<meta charset="UTF-8">
<title>Employee Management System</title>
<!-- Compiled and minified CSS -->
<link rel="stylesheet"
href="https://cdnjs.cloudflare.com/ajax/libs/materialize/1.0.0/css/materialize.min.css">
<!-- Compiled and minified JavaScript -->
<script
src="https://cdnjs.cloudflare.com/ajax/libs/materialize/1.0.0/js/materialize.min.js"></script>
</head>
<body style="max-width: 960px; margin: 16px auto; padding: 16px">
<h3>Update Employee</h3>
<!-- The th:action="@{/saveEmployee}" expression directs the form to POST to the /saveEmployee endpoint.
The th:object="${employee}" expression declares the model object to use for collecting the form data.
The three form fields, expressed with th:field, correspond to the fields in the Employee object. -->
<form th:action="@{/saveEmployee}" th:object="${employee}" method="post">
<div class="row">
<input type="hidden" id="id"
th:field="*{id}">
<div class="input-field col s6">
<input id="first_name" type="text" class="validate"
th:field="*{firstName}"> <label for="first_name">First
Name</label>
</div>
<div class="input-field col s6">
<input id="last_name" type="text" class="validate"
th:field="*{lastName}"> <label for="last_name">Last
Name</label>
</div>
</div>
<div class="row">
<div class="input-field col s6">
<input id="email" type="email" class="validate" th:field="*{email}">
<label for="email">Email</label>
</div>
</div>
<button type="submit" class="waves-effect waves-light btn">Update
Employee</button>
</form>
<br>
<!-- The link which sends GET request to "/" -->
<a th:href="@{/}"
class="blue-text">Back</a>
</body>
</html>
Congratulations! You have just developed a Spring Boot application! Run your application and go to the http://localhost:8080/ and see what you just made!
Thank you for reading this post. Is this post useful for you? If it is, I am happy. I would be glad for any comments like impressions, bugs, what you don’t understand about this post from you. Don't hesitate to contact me.
Share
If you like this post, please share!
Thank you for visiting my website. I would be glad if you like this website and continue having an interest in me.
Don't hesitate to contact me. 😎
Satoru Akiyama