Spring Boot – Thymeleaf 示例
Thymeleaf是一个基于 Java 的服务器端模板引擎,适用于 Web 和独立环境,能够处理 HTML、XML、JavaScript、CSS 甚至纯文本。它比 JPS 更强大,负责在 UI 上呈现动态内容。该引擎允许后端和前端开发人员在同一视图上并行工作。它可以直接访问 Java 对象和 Spring bean 并将它们与 UI 绑定。当我们创建任何 Web 应用程序时,它主要与 Spring MVC 一起使用。因此,让我们从一个例子开始,了解 Thymeleaf 如何与 Spring 框架配合使用。
项目设置
这里我们将对员工数据集执行 CRUD 操作。因此,为了构建它,我们必须添加以项目符号形式或在 pom.xml 中列出的某些依赖项。
- Spring Web(使用 Spring MVC 构建 Web 应用程序,包括 RESTful。使用 Apache Tomcat 作为默认嵌入式容器。)
- Spring Data JPA(使用 Spring Data 和 Hibernate 通过 Java Persistence API 将数据持久保存在 SQL 存储中。)
- Spring Boot Devtools(提供快速应用程序重启、LiveReload 和配置,以增强开发体验)
- MySQL 驱动程序(MySQL JDBC 和 R2DBC 驱动程序)
- Thymeleaf(用于 Web 和独立环境的服务器端 Java 模板引擎。允许 HTML 在浏览器中和静态原型中正确显示。)
POM.XML
- XML
<?xml version="1.0" encoding="UTF-8"?> <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https:/ /maven.apache.org/xsd/maven-4.0.0.xsd"> <modelVersion>4.0.0</modelVersion> <parent> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-parent</artifactId> <version>2.6.2</version> <relativePath/> <!-- lookup parent from repository --> </parent> <groupId>com.example</groupId> <artifactId>thymeleaf</artifactId> <version>0.0.1-SNAPSHOT</version> <name>thymeleaf</name> <description>Demo project for Spring Boot</description> <properties> <java.version>17</java.version> </properties> <dependencies> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-data-jpa</artifactId> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-thymeleaf</artifactId> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-web</artifactId> </dependency>
<dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-devtools</artifactId> <scope>runtime</scope> <optional>true</optional> </dependency> <dependency> <groupId>mysql</groupId> <artifactId>mysql-connector-java</artifactId> <scope>runtime</scope> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-test</artifactId> <scope>test</scope> </dependency> </dependencies>
<build> <plugins> <plugin> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-maven-plugin</artifactId> </plugin> </plugins> </build> </project> |
application.properties 文件
spring.jpa.hibernate.ddl-auto=update
spring.datasource.url=jdbc:mysql://localhost:3306/emp
spring.datasource.username=root
spring.datasource.password=root
spring.jpa.properties.hibernate.dialect=org.hibernate.dialect.MySQLInnoDBDialect
logs.level.org.hibernate.SQL=DEBUG
logs.level.org.hibernate.type=TRACE
Employee Pojo
这是用于存储员工数据的简单 pojo 类。
- Java
package com.microservice.modal;
import javax.persistence.Entity; import javax.persistence.GeneratedValue; import javax.persistence.GenerationType; import javax.persistence.Id;
@Entity public class Employee { @Id @GeneratedValue(strategy=GenerationType.IDENTITY) private long id; private String name; private String email;
public long getId() { return id; } public void setId(long id) { this.id = id; } public String getName() { return name; } public void setName(String name) { this.name = name; } public String getEmail() { return email; } public void setEmail(String email) { this.email = email; } } |
Employee Service interface and EmployeeServiceImpl class
- Java
package com.microservice.service;
import java.util.List;
import com.microservice.modal.Employee;
public interface EmployeeServices { List<Employee> getAllEmployee(); void save(Employee employee); Employee getById(Long id); void deleteViaId(long id); } |
EmployeeServiceImpl 类,实现 EmployeeSerivce 接口方法
- Java
package com.microservice.service;
import com.microservice.modal.Employee; import com.microservice.repository.EmployeeRepository; import java.util.List; import java.util.Optional; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Service;
@Service public class EmployeeServiceImpl implements EmployeeServices {
@Autowired private EmployeeRepository empRepo;
@Override public List<Employee> getAllEmployee() { return empRepo.findAll(); }
@Override public void save(Employee employee) { empRepo.save(employee); }
@Override public Employee getById(Long id) { Optional<Employee> optional = empRepo.findById(id); Employee employee = null; if (optional.isPresent()) employee = optional.get(); else throw new RuntimeException( "Employee not found for id : " + id); return employee; }
@Override public void deleteViaId(long id) { empRepo.deleteById(id); } } |
EmployeeRepository 接口
这里我们使用 JPA 进行通信并将对象保存到数据库中。
- Java
package com.microservice.repository;
import org.springframework.data.jpa.repository.JpaRepository; import org.springframework.stereotype.Repository;
import com.microservice.modal.Employee;
@Repository public interface EmployeeRepository extends JpaRepository<Employee,Long> {
} |
EmployeeController 类
这是控制器类,它主要控制数据流。它控制数据流入模型对象,并在数据发生变化时更新视图。所以这里我们用 Thymeleaf 映射我们的对象数据。
- 当用户在浏览器中输入 URL localhost:8080/时,请求将转到viewHomePage()方法,在此方法中,我们将获取员工列表并将其与键值对一起添加到模式中,然后返回index.html页面。在 index.html 页面中,键(allemplist)被标识为 java 对象,Thymeleaf 遍历列表并根据用户提供的模板生成动态内容。
- /addNew – 当用户单击“添加员工”按钮时,请求将转到addNewEmployee()方法。在此方法中,我们只需创建员工的空对象并将其发送回newemployee.html,以便用户可以在此空对象中填充数据,当用户点击“保存”按钮时,/save映射将运行并获取员工对象并将该对象保存到数据库中。
- /showFormForUpdate/{id} –此映射用于更新现有的员工数据。
- /deleteEmployee/{id} –此映射用于删除现有的员工数据。
- Java
package com.microservice.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.microservice.modal.Employee; import com.microservice.service.EmployeeServiceImpl;
@Controller public class EmployeeController {
@Autowired private EmployeeServiceImpl employeeServiceImpl;
@GetMapping("/") public String viewHomePage(Model model) { model.addAttribute("allemplist", employeeServiceImpl.getAllEmployee()); return "index"; }
@GetMapping("/addnew") public String addNewEmployee(Model model) { Employee employee = new Employee(); model.addAttribute("employee", employee); return "newemployee"; }
@PostMapping("/save") public String saveEmployee(@ModelAttribute("employee") Employee employee) { employeeServiceImpl.save(employee); return "redirect:/"; }
@GetMapping("/showFormForUpdate/{id}") public String updateForm(@PathVariable(value = "id") long id, Model model) { Employee employee = employeeServiceImpl.getById(id); model.addAttribute("employee", employee); return "update"; }
@GetMapping("/deleteEmployee/{id}") public String deleteThroughId(@PathVariable(value = "id") long id) { employeeServiceImpl.deleteViaId(id); return "redirect:/";
} } |
index.html
此页面用于显示员工列表。这里我们迭代控制器通过viewHomePage()方法发送的allemplist 对象。
- HTML
<!DOCTYPE html> <html lang="en" xmlns:th="http://www.thymeleaf.org"> <head> <meta charset="ISO-8859-1"> <title>Employee</title> <link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/4.1.3/css/bootstrap.min.css" integrity="sha384-MCw98/SFnGE8fJT3GXwEOngsV7Zt27NXFoaoApmYm81iuXoPkFOJwJ8ERdknLPMO" crossorigin="anonymous"> </head> <body> <div class="container my-2" align="center">
<h3>Employee List</h3> <a th:href="@{/addnew}" class="btn btn-primary btn-sm mb-3" >Add Employee</a> <table style="width:80%" border="1" class = "table table-striped table-responsive-md"> <thead> <tr> <th>Name</th> <th>Email</th> <th>Action</th> </tr> </thead> <tbody> <tr th:each="employee:${allemplist}"> <td th:text="${employee.name}"></td> <td th:text="${employee.email}"></td> <td> <a th:href="@{/showFormForUpdate/{id}(id=${employee.id})}" class="btn btn-primary">Update</a> <a th:href="@{/deleteEmployee/{id}(id=${employee.id})}" class="btn btn-danger">Delete</a> </td> </tr> </tbody> </table> </div> </body> </html> |
newemployee.html
此页面用于在数据库中添加新员工。在这里,我们只需在空白字段中提供值并单击提交按钮。然后员工的数据进入 saveEmployee ()方法并将数据保存到数据库中。
- HTML
<!DOCTYPE html> <html lang="en" xmlns:th="http://www.thymeleaf.org"> <head> <meta charset="ISO-8859-1"> <title>Employee Management System</title> <link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/4.1.3/css/bootstrap.min.css" integrity="sha384-MCw98/SFnGE8fJT3GXwEOngsV7Zt27NXFoaoApmYm81iuXoPkFOJwJ8ERdknLPMO" crossorigin="anonymous"> </head> <body> <div class="container"> <h1>Employee Management System</h1> <hr> <h2>Save Employee</h2>
<form action="#" th:action="@{/save}" th:object="${employee}" method="POST"> <input type="text" th:field="*{name}" placeholder="Employee Name" class="form-control mb-4 col-4"> <input type="text" th:field="*{email}" placeholder="Employee Email" class="form-control mb-4 col-4">
<button type="submit" class="btn btn-info col-2">Save Employee</button> </form>
<hr>
<a th:href="@{/}"> Back to Employee List</a> </div> </body> </html> |
update.html
此页面用于更新现有员工的数据。
- HTML
<!DOCTYPE html> <html lang="en" xmlns:th="http://www.thymeleaf.org"> <head> <meta charset="ISO-8859-1"> <title>Employee Management System</title>
<link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/4.1.3/css/bootstrap.min.css"> </head> <body> <div class="container"> <h1>Employee Management System</h1> <hr> <h2>Update Employee</h2>
<form action="#" th:action="@{/save}" th:object="${employee}" method="POST">
<!-- Add hidden form field to handle update --> <input type="hidden" th:field="*{id}" />
<input type="text" th:field="*{Name}" class="form-control mb-4 col-4">
<input type="text" th:field="*{email}" class="form-control mb-4 col-4">
<button type="submit" class="btn btn-info col-2"> Update Employee</button> </form>
<hr>
<a th:href = "@{/}"> Back to Employee List</a> </div> </body> </html> |