Spring Boot – Thymeleaf con ejemplo

Thymeleaf es un motor de plantillas basado en Java del lado del servidor para entornos web e independientes, capaz de procesar HTML, XML, JavaScript, CSS e incluso texto sin formato. Es más potente que JPS y responsable de la representación de contenido dinámico en la interfaz de usuario. El motor permite un trabajo paralelo de los desarrolladores de backend y frontend en la misma vista. Puede acceder directamente al objeto Java y Spring Beans y vincularlos con la interfaz de usuario. Y se usa principalmente con Spring MVC cuando creamos cualquier aplicación web. Entonces, comencemos con un ejemplo para comprender cómo funciona Thymeleaf con el marco Spring. 

Configuración del proyecto

Aquí vamos a realizar una operación cruda en el conjunto de datos del empleado. Entonces, para construir esto, debemos agregar ciertas dependencias que se enumeran en forma de viñetas o también en pom.xml. 

  • Spring Web (Cree aplicaciones web, incluidas RESTful, utilizando Spring MVC. Utiliza Apache Tomcat como contenedor incrustado predeterminado).
  • Spring Data JPA (persistencia de datos en almacenes SQL con la API de persistencia de Java usando Spring Data e Hibernate).
  • Spring Boot Devtools (Proporciona reinicios rápidos de aplicaciones, LiveReload y configuraciones para una experiencia de desarrollo mejorada)
  • Controlador MySQL (controlador MySQL JDBC y R2DBC)
  • Thymeleaf (motor de plantillas Java del lado del servidor para entornos web e independientes. Permite que HTML se muestre correctamente en navegadores y como prototipos estáticos).

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>

archivo 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

Empleado Pojo

Esta es la clase pojo simple que se usa para almacenar los datos de Employee. 

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

Interfaz de Employee Service y clase EmployeeServiceImpl

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

Clase EmployeeServiceImpl que implementa los métodos de interfaz de EmployeeService

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

Interfaz de repositorio de empleados

Aquí estamos usando JPA para comunicarnos y guardar el objeto en la base de datos.

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> {
 
}

Clase EmployeeController

Esta es la clase de controlador que básicamente controla el flujo de datos. Controla el flujo de datos en el objeto modelo y actualiza la vista cada vez que cambian los datos. Así que aquí estamos mapeando nuestros datos de objetos con Thymeleaf. 

  • Cuando el usuario escribe la URL localhost:8080/ en el navegador, la solicitud va al método viewHomePage() y en este método buscamos la lista de empleados y la agregamos al modal con clave, par de valores y devolvemos la página index.html . En la página index.html, la clave (allemplist) se identifica como un objeto java y Thymeleaf itera sobre la lista y genera contenido dinámico según la plantilla proporcionada por el usuario.
  • /addNew:   cuando el usuario hace clic en el botón Agregar empleado , la solicitud va al método addNewEmployee() . Y en este método, simplemente creamos el objeto vacío del empleado y lo enviamos de regreso a newemployee.html para que el usuario pueda completar los datos en este objeto vacío y cuando el usuario presiona el botón Guardar, se ejecuta el mapeo /guardar y obtener el objeto del empleado y guarde ese objeto en la base de datos.
  • /showFormForUpdate/{id}: esta asignación es para actualizar los datos de empleados existentes.
  • /deleteEmployee/{id}: esta asignación es para eliminar los datos de empleados existentes.

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

índice.html

Esta página se utiliza para mostrar la lista de empleados. Aquí estamos iterando sobre el objeto allemplist que envía nuestro controlador desde el método viewHomePage()

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>

nuevoempleado.html

Esta página se utiliza para agregar nuevos empleados en la base de datos. Aquí simplemente proporcionamos el valor en campos vacíos y hacemos clic en el botón Enviar. Luego, los datos del empleado van al método saveEmployee() y guardan los datos en la base de datos. 

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>

actualizar.html

Esta página se utiliza para actualizar los datos del empleado existente. 

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>

Producción:

Publicación traducida automáticamente

Artículo escrito por shubhamp338 y traducido por Barcelona Geeks. The original can be accessed here. Licence: CCBY-SA

Deja una respuesta

Tu dirección de correo electrónico no será publicada. Los campos obligatorios están marcados con *