Spring Boot – Thymeleaf 示例

Thymeleaf是一个基于 Java 的服务器端模板引擎,适用于 Web 和独立环境,能够处理 HTML、XML、JavaScript、CSS 甚至纯文本。它比JPS更强大,负责UI上的动态内容渲染。该引擎允许后端和前端开发人员在同一视图上并行工作。它可以直接访问java对象和spring bean并将它们与UI绑定。当我们创建任何 Web 应用程序时,它主要与 Spring MVC 一起使用。那么让我们从一个示例开始来了解 Thymeleaf 如何与 Spring 框架配合使用。 

项目设置
这里我们将对Employee数据集进行增删改查操作。因此,为了构建它,我们必须添加某些依赖项,这些依赖项以项目符号形式列出或在 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 在浏览器中正确显示并作为静态原型。)

<?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
logging.level.org.hibernate.SQL=DEBUG
logging.level.org.hibernate.type=TRACE


Employee Pojo
这是一个简单的 pojo 类,用于存储雇员的数据。

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 接口和EmployeeServiceImpl 实现

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);
}


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 接口:

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 类

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:/";

    }
}

  • 这是控制器类,主要控制数据流。它控制数据流进入模型对象,并在数据发生变化时更新视图。在这里,我们使用 Thymeleaf 映射对象数据。
  • 当用户在浏览器上输入 URL localhost:8080/ 时,请求将转到 viewHomePage() 方法,在该方法中,我们将获取雇员列表,并将其添加到带有键、值对的模态中,然后返回 index.html 页面。在 index.html 页面中,键(allemplist)被识别为一个 java 对象,Thymeleaf 会遍历该列表,并根据用户提供的模板生成动态内容。
  • /addNew - 当用户点击添加员工按钮时,请求将转到 addNewEmployee() 方法。在该方法中,我们只需创建雇员的空对象,并将其发送回 newemployee.html,这样用户就可以在这个空对象中填写数据。当用户点击保存按钮时,/save 映射就会运行,并获取雇员的对象并将该对象保存到数据库中。
  • /showFormForUpdate/{id} - 该映射用于更新现有雇员数据。
  • /deleteEmployee/{id} - 该映射用于删除现有雇员数据。

index.html

该页面用于显示员工列表。在这里,我们对控制器通过 viewHomePage() 方法发送的 allemplist 对象进行迭代。

<!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() 方法,并保存到数据库中。

<!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

该页面用于更新现有雇员的数据。

<!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>