Spring Boot

SpringBoot

Tutorial SpringBoot: Vista en Spring MVC con Thymeleaf

Spring Boot Thymeleaf: integración y uso. Domina la integración y uso de Thymeleaf en Spring Boot con ejemplos prácticos y detallados.

Aprende SpringBoot GRATIS y certifícate

Agregar el starter thymeleaf y configuración implícita y explícita de templates

Para integrar Thymeleaf en una aplicación Spring Boot, es necesario agregar el starter correspondiente que proporciona las dependencias y configuraciones básicas. En el caso de utilizar Maven, se debe incluir la siguiente dependencia en el pom.xml:

<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-thymeleaf</artifactId>
</dependency>

Si se emplea Gradle, se añadiría en el build.gradle:

implementation 'org.springframework.boot:spring-boot-starter-thymeleaf'

Una vez agregado el starter, Spring Boot detecta automáticamente la presencia de Thymeleaf y realiza una configuración implícita. Por defecto, las plantillas deben ubicarse en el directorio src/main/resources/templates, y los archivos deben tener la extensión .html.

La configuración implícita de Thymeleaf incluye varias propiedades predeterminadas que facilitan su uso sin necesidad de ajustes adicionales. Algunas de estas propiedades son:

  • spring.thymeleaf.prefix=classpath:/templates/
  • spring.thymeleaf.suffix=.html
  • spring.thymeleaf.mode=HTML
  • spring.thymeleaf.encoding=UTF-8
  • spring.thymeleaf.cache=true

No obstante, en proyectos donde se requiere personalizar el comportamiento de las plantillas, es posible realizar una configuración explícita. Esto se logra modificando las propiedades en el archivo application.properties o application.yml.

Por ejemplo, para cambiar la ubicación de las plantillas, se puede ajustar la propiedad spring.thymeleaf.prefix. Si se desea que las plantillas se encuentren en classpath:/mis-plantillas/, se configuraría de la siguiente manera:

spring.thymeleaf.prefix=classpath:/mis-plantillas/

Si es necesario utilizar una extensión diferente para los archivos de plantilla, como .tmpl, se modifica la propiedad spring.thymeleaf.suffix:

spring.thymeleaf.suffix=.tmpl

Durante el desarrollo, puede ser útil desactivar el cacheo de las plantillas para reflejar los cambios al instante:

spring.thymeleaf.cache=false

Además de las propiedades mencionadas, existen otras opciones que permiten personalizar aspectos avanzados del motor de plantillas. Por ejemplo, es posible especificar el modo de procesamiento (spring.thymeleaf.mode) o definir un gestor de mensajes para la internacionalización (spring.thymeleaf.message-source).

En situaciones que requieren una configuración más detallada, se puede definir un bean de tipo SpringTemplateEngine en el código Java. Esto proporciona mayor control sobre los componentes internos de Thymeleaf. A continuación, se muestra un ejemplo:

@Bean
public SpringTemplateEngine templateEngine(ITemplateResolver templateResolver) {
    SpringTemplateEngine templateEngine = new SpringTemplateEngine();
    templateEngine.setTemplateResolver(templateResolver);
    templateEngine.addDialect(new SpringStandardDialect());
    return templateEngine;
}

En este fragmento, se crea un bean de SpringTemplateEngine y se añade un dialecto estándar de Spring. Esta configuración permite adaptar el comportamiento del motor de plantillas a las necesidades específicas de la aplicación.

Al personalizar las configuraciones, es fundamental asegurar la coherencia y compatibilidad con el resto de componentes del proyecto. La utilización adecuada de las propiedades de configuración facilita el mantenimiento y evolución de la aplicación, garantizando un correcto funcionamiento del sistema de vistas.

Creación de plantillas html y uso en controladores MVC

En el desarrollo de aplicaciones web con Spring Boot 3, el uso de plantillas HTML dinámicas es esencial para generar vistas interactivas. Thymeleaf es un motor de plantillas que permite crear páginas HTML enriquecidas, integrándolas de manera fluida con los controladores MVC de Spring.

Para comenzar, las plantillas HTML deben ubicarse en el directorio src/main/resources/templates. Esta ubicación es reconocida por defecto gracias a la configuración implícita de Spring Boot. Cada plantilla es un archivo HTML que puede aprovechar las funcionalidades de Thymeleaf para generar contenido dinámico.

Un ejemplo sencillo de una plantilla Thymeleaf denominada index.html podría ser:

<!DOCTYPE html>
<html xmlns:th="http://www.thymeleaf.org">
<head>
    <title>Página de Inicio</title>
    <meta charset="UTF-8">
</head>
<body>
    <h1 th:text="'Bienvenido, ' + ${nombreUsuario} + '!'"></h1>
    <p>Esta es una aplicación de ejemplo usando Thymeleaf.</p>
</body>
</html>

En esta plantilla, se utiliza el atributo th:text para insertar el valor de la variable nombreUsuario en el contenido del encabezado <h1>. La expresión ${nombreUsuario} es una forma de acceder al modelo de datos proporcionado por el controlador.

Para que esta plantilla funcione correctamente, es necesario crear un controlador MVC que maneje las peticiones y proporcione los datos al modelo. Un ejemplo de controlador sería:

@Controller
public class InicioController {

    @GetMapping("/")
    public String mostrarPaginaInicio(Model model) {
        model.addAttribute("nombreUsuario", "María");
        return "index";
    }
}

En este controlador, la anotación @Controller indica que es un componente que maneja solicitudes web. El método mostrarPaginaInicio está mapeado a la ruta / mediante @GetMapping("/"). Dentro del método, se agrega el atributo nombreUsuario al modelo, asignándole el valor "María". Finalmente, se retorna el nombre de la plantilla a renderizar, en este caso "index".

Es importante destacar que el objeto Model es clave para pasar datos desde el controlador a la vista. Al agregar atributos al modelo, estos estarán disponibles en la plantilla Thymeleaf correspondiente.

Al arrancar la aplicación y acceder a la ruta raíz (/), el navegador mostrará la página generada:

Bienvenido, María!
Esta es una aplicación de ejemplo usando Thymeleaf.

La integración entre la plantilla y el controlador permite generar contenido dinámico basado en los datos proporcionados por la lógica de la aplicación. Además, Thymeleaf proporciona una sintaxis natural que facilita el desarrollo y mantenimiento de las vistas.

Para manejar múltiples rutas y plantillas, se pueden definir más métodos en el controlador o crear otros controladores según sea necesario. Por ejemplo, para agregar una página de contacto:

@GetMapping("/contacto")
public String mostrarPaginaContacto(Model model) {
    model.addAttribute("email", "contacto@ejemplo.com");
    return "contacto";
}

Y su correspondiente plantilla contacto.html:

<!DOCTYPE html>
<html xmlns:th="http://www.thymeleaf.org">
<head>
    <title>Contacto</title>
    <meta charset="UTF-8">
</head>
<body>
    <h1>Información de Contacto</h1>
    <p>Email: <span th:text="${email}"></span></p>
</body>
</html>

En este caso, se añade al modelo el atributo email, que luego es utilizado en la plantilla para mostrar la información de contacto.

Es posible también pasar objetos más complejos al modelo, como colecciones o entidades. Por ejemplo:

@GetMapping("/productos")
public String listarProductos(Model model) {
    List<Producto> productos = servicioProducto.obtenerTodosLosProductos();
    model.addAttribute("productos", productos);
    return "lista-productos";
}

En la plantilla lista-productos.html, se puede iterar sobre la lista de productos:

<!DOCTYPE html>
<html xmlns:th="http://www.thymeleaf.org">
<head>
    <title>Lista de Productos</title>
    <meta charset="UTF-8">
</head>
<body>
    <h1>Productos Disponibles</h1>
    <ul>
        <li th:each="producto : ${productos}">
            <span th:text="${producto.nombre}">Nombre del Producto</span> - 
            <span th:text="${producto.precio}">Precio</span>
        </li>
    </ul>
</body>
</html>

Aquí, el atributo th:each permite iterar sobre la colección productos, y para cada elemento, se muestran sus propiedades nombre y precio.

La comunicación entre el controlador y la vista se basa en el modelo de datos que se compone en el controlador. Los controladores MVC en Spring Boot facilitan la gestión de las solicitudes HTTP y la preparación de los datos necesarios para las vistas.

Además, es posible manejar formularios y procesar la información enviada por el usuario. Por ejemplo, para mostrar un formulario de registro:

@GetMapping("/registro")
public String mostrarFormularioRegistro(Model model) {
    model.addAttribute("usuario", new Usuario());
    return "formulario-registro";
}

Y la plantilla formulario-registro.html:

<!DOCTYPE html>
<html xmlns:th="http://www.thymeleaf.org">
<head>
    <title>Formulario de Registro</title>
    <meta charset="UTF-8">
</head>
<body>
    <h1>Registro de Usuario</h1>
    <form action="#" th:action="@{/registro}" th:object="${usuario}" method="post">
        <label for="nombre">Nombre:</label>
        <input type="text" id="nombre" th:field="*{nombre}" />
        <br/>
        <label for="email">Email:</label>
        <input type="email" id="email" th:field="*{email}" />
        <br/>
        <button type="submit">Registrar</button>
    </form>
</body>
</html>

El atributo th:object vincula el formulario con el objeto usuario del modelo, y th:field se utiliza para enlazar los campos del formulario con las propiedades del objeto.

Para procesar el formulario, se define un método en el controlador que maneje las solicitudes POST:

@PostMapping("/registro")
public String procesarFormularioRegistro(@ModelAttribute Usuario usuario) {
    servicioUsuario.guardar(usuario);
    return "redirect:/";
}

La anotación @ModelAttribute indica que el objeto usuario debe ser poblado con los datos del formulario. Después de procesar y guardar el usuario, se redirige al inicio.

Esta interacción de datos entre el usuario, el controlador y las vistas permite construir aplicaciones web robustas y escalables. El uso eficiente de las plantillas HTML y los controladores MVC es fundamental para lograr una arquitectura limpia y mantenible.

Además, es posible utilizar fragmentos de plantillas para reutilizar código. Por ejemplo, crear una cabecera común:

<!-- fragmentos/header.html -->
<!DOCTYPE html>
<html xmlns:th="http://www.thymeleaf.org">
<head>
    <title th:insert="~{::title}">Aplicación</title>
    <meta charset="UTF-8">
</head>
<body>
    <header>
        <h1>Mi Aplicación</h1>
    </header>
    <div th:insert="~{::body}"></div>
</body>
</html>

Y en las plantillas, incluir este fragmento:

<!-- index.html -->
<!DOCTYPE html>
<html xmlns:th="http://www.thymeleaf.org" th:replace="fragments/header :: header">
<title>Página de Inicio</title>
<div>
    <!-- Contenido de la página -->
</div>
</html>

Con esto, se consigue una estructura consistente en todas las páginas, facilitando el mantenimiento y la actualización del diseño.

En resumen, la creación de plantillas HTML y su uso en controladores MVC con Spring Boot 3 y Thymeleaf permite desarrollar aplicaciones web dinámicas de manera eficiente. La integración entre el modelo de datos, las vistas y los controladores es esencial para ofrecer una experiencia de usuario fluida y personalizada.

Uso de expresiones en las plantillas HTML

Las expresiones en Thymeleaf son fundamentales para generar contenido dinámico en las plantillas HTML de una aplicación Spring Boot 3. Permiten interactuar con los datos del modelo, realizar operaciones lógicas y controlar la representación de elementos en la vista.

Thymeleaf utiliza una variedad de expresiones para acceder y manipular datos:

  • Expresiones de variable (${...}): acceden a variables del modelo.
  <p th:text="${mensajeBienvenida}">Mensaje de bienvenida</p>
  • Expresiones de selección (*{...}): simplifican el acceso a propiedades dentro de un objeto seleccionado.
  <form th:object="${usuario}">
      <input type="text" th:field="*{nombre}" />
  </form>
  • Expresiones literales: permiten usar valores literales como cadenas o números.
  <span th:text="'Hola, ' + ${usuario.nombre} + '!'">Saludo</span>
  • Expresiones de mensaje (#{...}): acceden a mensajes definidos en archivos de propiedades para internacionalización.
  <h1 th:text="#{titulo.pagina}">Título predeterminado</h1>
  • Expresiones de enlace (@{...}): generan URLs dinámicas.
  <a th:href="@{/productos/{id}(id=${producto.id})}">Ver Producto</a>

Para manipular elementos HTML, Thymeleaf introduce atributos especiales prefijados con th::

  • th:text: reemplaza el contenido de un elemento con el resultado de una expresión, asegurando el escape de caracteres.
  <p th:text="${descripcion}">Descripción del producto</p>
  • th:utext: similar a th:text, pero no escapa caracteres, permitiendo contenido HTML.
  <div th:utext="${contenidoHTML}">Contenido HTML</div>
  • th:if y th:unless: controlan la renderización de elementos según una condición lógica.
  <span th:if="${producto.enOferta}">¡Oferta especial!</span>
  <span th:unless="${producto.enStock}">Producto agotado</span>
  • th:each: itera sobre colecciones para generar listas o tablas dinámicas.
  <ul>
      <li th:each="item : ${items}">
          <span th:text="${item.nombre}">Nombre del ítem</span>
      </li>
  </ul>

Dentro de las expresiones, es posible utilizar operadores lógicos y relacionales para evaluar condiciones:

<p th:text="${usuario.edad >= 18} ? 'Adulto' : 'Menor de edad'">Categoría de edad</p>

Además, Thymeleaf proporciona objetos de utilidad para manipular datos:

  • #strings: métodos para cadenas. Por ejemplo, convertir a mayúsculas:
  <span th:text="${#strings.toUpperCase(usuario.apellido)}">Apellido en mayúsculas</span>
  • #dates: formateo de fechas.
  <span th:text="${#dates.format(pedido.fecha, 'dd/MM/yyyy')}">Fecha del pedido</span>
  • #numbers: formateo de números.
  <span th:text="${#numbers.formatDecimal(producto.precio, 2)}">Precio</span>

Es posible acceder a propiedades anidadas usando la notación de punto:

<p th:text="${pedido.cliente.nombre}">Nombre del Cliente</p>

Al iterar sobre colecciones con th:each, se pueden utilizar variables de estado de la iteración:

<tr th:each="item, iterStat : ${items}">
    <td th:text="${iterStat.index}">Índice</td>
    <td th:text="${item.nombre}">Nombre</td>
</tr>

Esto permite, por ejemplo, mostrar el índice de cada elemento.

Para definir valores por defecto, se utiliza el operador Elvis (?:):

<span th:text="${usuario.alias} ?: 'Anónimo'">Nombre de Usuario</span>

Al controlar atributos HTML, se pueden condicionar su presencia o valor:

<input type="text" th:attr="readonly=${!editable}" />

En este caso, si editable es falso, el campo será de solo lectura.

Es importante tener en cuenta la seguridad al usar expresiones. Thymeleaf escapa automáticamente los valores en th:text para prevenir inyecciones de código. Sin embargo, al usar th:utext, hay que asegurarse de que el contenido es seguro, ya que no se realiza escape.

Un ejemplo completo que integra varias expresiones:

<!DOCTYPE html>
<html xmlns:th="http://www.thymeleaf.org">
<head>
    <title>Perfil de Usuario</title>
    <meta charset="UTF-8">
</head>
<body>
    <h1>Perfil de <span th:text="${usuario.nombre}">Nombre</span></h1>
    <p>Edad: <span th:text="${usuario.edad}">0</span> años</p>
    <p th:if="${usuario.fechaNacimiento != null}">
        Fecha de Nacimiento: <span th:text="${#dates.format(usuario.fechaNacimiento, 'dd MMM yyyy')}">Fecha</span>
    </p>
    <p th:unless="${usuario.fechaNacimiento != null}">
        Fecha de Nacimiento: **No proporcionada**
    </p>
    <h2>Intereses</h2>
    <ul>
        <li th:each="interes : ${usuario.intereses}" th:text="${interes}">Interés</li>
    </ul>
    <a th:href="@{/usuarios/editar/{id}(id=${usuario.id})}">Editar Perfil</a>
</body>
</html>

En este ejemplo:

  • Se muestra el nombre y la edad del usuario.
  • Se verifica si fechaNacimiento no es nulo para mostrarla formateada.
  • Se lista la colección de intereses del usuario.
  • Se proporciona un enlace dinámico para editar el perfil.

Algunas buenas prácticas al utilizar expresiones en Thymeleaf:

  • Mantener la lógica en las plantillas simple y enfocada en la presentación.
  • Utilizar el controlador para preparar los datos y evitar cálculos complejos en las vistas.
  • Aprovechar los objetos de utilidad para operaciones comunes.
  • Escapar siempre los datos que provienen del usuario o de fuentes externas.
  • Organizar las plantillas utilizando fragmentos para reutilizar componentes comunes y mejorar la mantenibilidad.

Las expresiones en Thymeleaf son una herramienta versátil que, combinada con los atributos proporcionados, permite crear vistas ricas y dinámicas. Su correcta utilización mejora la interacción entre el modelo, la vista y el controlador, facilitando el desarrollo de aplicaciones web robustas con Spring Boot 3.

Diferencias de Thymeleaf con JSP/JSTL

En el desarrollo de aplicaciones web con Spring Boot 3, es común utilizar motores de plantillas para gestionar la presentación de la interfaz de usuario. Dos de las opciones más populares son Thymeleaf y JSP/JSTL. Aunque ambos sirven para generar contenido dinámico en páginas web, existen diferencias significativas entre ellos que afectan la forma en que se construyen y mantienen las aplicaciones.

Thymeleaf es un motor de plantillas moderno que permite crear vistas en HTML que pueden ser visualizadas directamente en un navegador sin necesidad de un servidor de aplicaciones. Esto se debe a que las plantillas Thymeleaf son documentos HTML válidos, lo que facilita el trabajo conjunto entre desarrolladores y diseñadores. Por otro lado, JSP (JavaServer Pages) es una tecnología más antigua que requiere ser compilada en tiempo de ejecución en servlets, no pudiendo ser visualizada directamente sin un contenedor de servlets.

Una de las principales diferencias radica en la sintaxis utilizada para insertar datos dinámicos en las vistas. En Thymeleaf, se emplean atributos personalizados en etiquetas HTML, como th:text para modificar el contenido de un elemento:

<span th:text="${mensaje}">Texto por defecto</span>

En cambio, JSP/JSTL utiliza expresiones incrustadas y etiquetas personalizadas que pueden dificultar la legibilidad del código:

<span>${mensaje}</span>

O con JSTL:

<c:out value="${mensaje}" />

La capacidad de Thymeleaf para conservar la plantilla legible sin procesamiento adicional hace que la colaboración con equipos de diseño sea más fluida. Los diseñadores pueden abrir y editar las plantillas HTML sin interferir con el código funcional, lo que no es tan sencillo con JSP, ya que mezcla código Java y HTML, resultando en archivos más complejos.

En cuanto al rendimiento, Thymeleaf ofrece mejoras significativas respecto a JSP/JSTL. Al no requerir compilación en tiempo de ejecución, las aplicaciones con Thymeleaf pueden tener tiempos de carga más rápidos. Además, Thymeleaf implementa una gestión de caché eficiente para las plantillas, optimizando el uso de recursos y reduciendo la carga en el servidor.

Otro aspecto diferencial es el soporte para expresiones lógicas y de control. Thymeleaf proporciona atributos como th:if, th:unless y th:each para controlar la renderización de elementos HTML de forma declarativa:

<div th:if="${usuarioAutenticado}">
    <p>Bienvenido, <span th:text="${usuario.nombre}">Usuario</span></p>
</div>

En JSP/JSTL, se requiere el uso de etiquetas de la biblioteca JSTL para lograr funcionalidades similares, lo que puede aumentar la complejidad del código:

<c:if test="${usuarioAutenticado}">
    <p>Bienvenido, ${usuario.nombre}</p>
</c:if>

Además, Thymeleaf facilita la internacionalización mediante el uso de mensajes y recursos externos con el atributo th:text y expresiones de mensajes:

<p th:text="#{mensaje.bienvenida}">Texto de bienvenida</p>

Mientras que en JSP/JSTL, es necesario configurar el estándar de etiquetas de internacionalización de JSTL y usar las correspondientes etiquetas:

<fmt:message key="mensaje.bienvenida" />

En términos de integración con Spring MVC, Thymeleaf está diseñado para trabajar de forma natural con el modelo de datos y los controladores de Spring. Soporta directamente la validación y el enlace de datos en formularios, utilizando la notación th:field:

<form th:action="@{/registro}" th:object="${usuario}" method="post">
    <input type="text" th:field="*{nombre}" />
    <button type="submit">Registrar</button>
</form>

Con JSP, el manejo de formularios y la vinculación de datos requieren una configuración adicional y no son tan intuitivos. Se suele depender de bibliotecas adicionales o escribir código más detallado para lograr la misma funcionalidad.

La extensibilidad es otra ventaja de Thymeleaf. Permite crear dialectos personalizados que amplían sus capacidades, facilitando la incorporación de nuevas funcionalidades y adaptándose a necesidades específicas. En contraste, JSP tiene limitaciones en su extensibilidad y está más vinculado a la tecnología subyacente de servlets.

En cuanto a la seguridad, Thymeleaf incorpora mecanismos para evitar vulnerabilidades comunes como la inyección de scripts. Escapa automáticamente los datos al usar atributos como th:text, protegiendo la aplicación sin requerir configuraciones adicionales. Por el contrario, en JSP, el desarrollador debe ser más cuidadoso y utilizar explícitamente funciones de escape o etiquetas como <c:out> para prevenir riesgos de seguridad.

La gestión de plantillas en Thymeleaf es más flexible gracias a la posibilidad de utilizar fragmentos reutilizables. Con la directiva th:replace o th:insert, se pueden incluir fragmentos de otras plantillas, promoviendo la modularidad:

<!DOCTYPE html>
<html xmlns:th="http://www.thymeleaf.org">
<head>
    <title>Aplicación</title>
</head>
<body>
    <header th:replace="fragments/header :: header"></header>
    <div th:replace="fragments/content :: content"></div>
    <footer th:replace="fragments/footer :: footer"></footer>
</body>
</html>

En JSP, aunque es posible incluir archivos con la directiva <%@ include %> o usar etiquetas personalizadas, la sintaxis es menos intuitiva y puede complicar la estructura de las vistas.

Por último, es relevante mencionar la evolución tecnológica y el soporte a largo plazo. Thymeleaf es una tecnología más reciente y activa, alineada con las prácticas modernas de desarrollo web. Por su parte, JSP/JSTL está considerado una tecnología más obsoleta, con menor atención en la comunidad y en actualizaciones futuras.

En resumen, mientras que JSP/JSTL fue una solución eficaz en el pasado para generar contenido dinámico en aplicaciones Java, Thymeleaf ofrece una alternativa más moderna, eficiente y amigable con el desarrollo contemporáneo. Su integración con Spring Boot 3, junto con sus ventajas en legibilidad, rendimiento y seguridad, lo convierten en una opción preferida para el desarrollo de vistas en aplicaciones basadas en Spring.

Otros motores de plantillas como Freemarker, Mustache

Además de Thymeleaf, existen otros motores de plantillas que pueden integrarse con Spring Boot 3 para generar vistas dinámicas en aplicaciones web. Dos de los más populares son Freemarker y Mustache. Estos motores ofrecen alternativas con distintas características y sintaxis, adaptándose a diferentes necesidades y preferencias de desarrollo.

Freemarker es un motor de plantillas basado en texto que permite generar cualquier tipo de texto a partir de datos proporcionados por la aplicación. Su sintaxis es poderosa y flexible, ofreciendo muchas funcionalidades para procesar y mostrar datos. Por otro lado, Mustache sigue el principio de lógica mínima, proporcionando una sintaxis sencilla y fácil de aprender, evitando la complejidad en las plantillas.

Integración de Freemarker en Spring Boot 3

Para utilizar Freemarker en una aplicación Spring Boot, es necesario agregar el starter correspondiente en el archivo de dependencias. Si se emplea Maven, se incluiría lo siguiente en el pom.xml:

<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-freemarker</artifactId>
</dependency>

Con Gradle, la dependencia se añade en el build.gradle:

implementation 'org.springframework.boot:spring-boot-starter-freemarker'

Una vez agregada la dependencia, Spring Boot autoconfigura Freemarker, estableciendo las plantillas en el directorio src/main/resources/templates por defecto, con la extensión .ftl.

Un ejemplo de plantilla Freemarker llamada saludo.ftl podría ser:

<!DOCTYPE html>
<html>
<head>
    <title>Saludo</title>
    <meta charset="UTF-8">
</head>
<body>
    <h1>Hola, ${nombreUsuario}!</h1>
    <p>Bienvenido a nuestra aplicación.</p>
</body>
</html>

En esta plantilla, la variable ${nombreUsuario} se reemplaza por el valor proporcionado por el modelo en el controlador. Un controlador sencillo podría ser:

@Controller
public class SaludoController {

    @GetMapping("/freemarker")
    public String mostrarSaludo(Model model) {
        model.addAttribute("nombreUsuario", "Carlos");
        return "saludo";
    }
}

Al acceder a /freemarker, el usuario verá la página generada con su nombre en el saludo.

Freemarker ofrece potentes directivas y expresiones para manipular los datos. Por ejemplo, para iterar sobre una lista de elementos:

<ul>
<#list productos as producto>
    <li>${producto.nombre} - ${producto.precio?string.currency}</li>
</#list>
</ul>

En este fragmento, #list es una directiva que permite recorrer la colección productos, y ${producto.nombre} accede a las propiedades de cada objeto.

Freemarker soporta también condicionales, macros y funciones definidas por el usuario, proporcionando gran flexibilidad en el diseño de las vistas.

Integración de Mustache en Spring Boot 3

Para incorporar Mustache en una aplicación Spring Boot, se debe agregar el siguiente starter en el archivo de dependencias. En Maven, se añade al pom.xml:

<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-mustache</artifactId>
</dependency>

Con Gradle, se incluye en el build.gradle:

implementation 'org.springframework.boot:spring-boot-starter-mustache'

Spring Boot configura automáticamente Mustache, ubicando las plantillas en src/main/resources/templates, con la extensión .mustache.

Una plantilla sencilla llamada bienvenida.mustache podría ser:

<!DOCTYPE html>
<html>
<head>
    <title>Bienvenida</title>
    <meta charset="UTF-8">
</head>
<body>
    <h1>Bienvenido, {{nombreUsuario}}!</h1>
    <p>Gracias por visitar nuestro sitio.</p>
</body>
</html>

En este caso, {{nombreUsuario}} es una etiqueta que será reemplazada por el valor correspondiente en el modelo. El controlador asociado sería similar:

@Controller
public class BienvenidaController {

    @GetMapping("/mustache")
    public String mostrarBienvenida(Model model) {
        model.addAttribute("nombreUsuario", "Lucía");
        return "bienvenida";
    }
}

Mustache utiliza una sintaxis minimalista, sin lógica compleja en las plantillas. Para iterar sobre una lista, se emplea:

<ul>
{{#productos}}
    <li>{{nombre}} - {{precio}}</li>
{{/productos}}
</ul>

Aquí, {{#productos}} inicia una sección que se repetirá para cada elemento en la colección productos. La lógica mínima de Mustache promueve la separación entre la vista y la lógica de negocio, manteniendo las plantillas simples y limpias.

Comparativa entre Freemarker, Mustache y Thymeleaf

Si bien Thymeleaf es ampliamente utilizado con Spring Boot, Freemarker y Mustache ofrecen alternativas con características distintivas:

Sintaxis y complejidad:

  • Freemarker: Ofrece una sintaxis rica y potente, permitiendo lógica compleja en las plantillas. Es ideal para proyectos que requieren gran flexibilidad y control sobre la presentación.
  • Mustache: Sigue el principio de lógica mínima, evitando la inclusión de código de programación en las plantillas. Favorece la simplicidad y la separación de responsabilidades.
  • Thymeleaf: Combina una sintaxis elegante con la capacidad de previsualizar las plantillas como HTML estático, facilitando el trabajo con diseñadores.

Integración con Spring Boot:

Los tres motores cuentan con starters que facilitan su integración y configuración automática en aplicaciones Spring Boot 3.

Todos permiten acceder al modelo proporcionado por el controlador y utilizarlo en las vistas.

Características adicionales:

  • Freemarker: Soporta macros, funciones y configuraciones avanzadas.
  • Mustache: Enfocado en la simplicidad, sin añadir funcionalidades más allá de las básicas.
  • Thymeleaf: Ofrece una buena integración con formularios, internacionalización y fragmentos reutilizables.

Configuración avanzada y personalización

En casos donde la configuración por defecto no es suficiente, es posible personalizar el comportamiento de Freemarker y Mustache mediante propiedades en el archivo application.properties o application.yml.

Por ejemplo, para cambiar la codificación de las plantillas en Freemarker:

spring.freemarker.charset=UTF-8
spring.freemarker.template-loader-path=classpath:/otras-plantillas/

Para Mustache, para desactivar el uso de caché durante el desarrollo:

spring.mustache.cache=false

Además, se pueden crear beans de configuración personalizada si se requiere un control más detallado sobre el motor de plantillas.

Uso de motores de plantillas en proyectos reales

La elección entre Freemarker, Mustache o Thymeleaf depende de las necesidades específicas del proyecto y las preferencias del equipo de desarrollo. Es esencial considerar factores como:

  • La complejidad de las vistas y la lógica necesaria en las plantillas.
  • La colaboración con diseñadores y la necesidad de previsualizar las plantillas sin un servidor.
  • Las prácticas de desarrollo y la preferencia por mantener la lógica fuera de las vistas.

En proyectos donde se requiere una gran capacidad de personalización y control sobre la presentación, Freemarker puede ser la opción más adecuada. Si se busca mantener las plantillas lo más simples posible, delegando la lógica al controlador, Mustache ofrece un enfoque minimalista y efectivo.

Es importante experimentar con los diferentes motores y evaluar cuál se adapta mejor al flujo de trabajo y a las exigencias del proyecto en cuestión.

La disponibilidad de múltiples motores de plantillas en Spring Boot 3 demuestra la flexibilidad del framework para adaptarse a distintas filosofías de desarrollo. Con opciones como Freemarker, Mustache y Thymeleaf, los desarrolladores tienen la libertad de elegir la herramienta que mejor se ajuste a sus necesidades, optimizando la productividad y la calidad del código.

Explorar y comprender las características de cada motor permite tomar decisiones informadas y sacar el máximo provecho de las capacidades que ofrecen para construir aplicaciones web robustas y mantenibles.

Aprende SpringBoot GRATIS online

Ejercicios de esta lección Vista en Spring MVC con Thymeleaf

Evalúa tus conocimientos de esta lección Vista en Spring MVC con Thymeleaf con nuestros retos de programación de tipo Test, Puzzle, Código y Proyecto con VSCode, guiados por IA.

Web y Test Starters

Spring Boot
Puzzle

Entidades JPA

Spring Boot
Test

Repositorios reactivos

Spring Boot
Test

Inserción de datos

Spring Boot
Test

Borrar datos de base de datos

Spring Boot
Test

Controladores Spring MVC

Spring Boot
Código

CRUD Customers Spring MVC + Spring Data JPA

Spring Boot
Proyecto

Backend API REST con Spring Boot

Spring Boot
Proyecto

Operadores Reactivos

Spring Boot
Puzzle

Controladores Spring REST

Spring Boot
Código

Uso de Spring con Thymeleaf

Spring Boot
Puzzle

Crear entidades JPA

Spring Boot
Código

Registro de usuarios

Spring Boot
Test

CRUD y JPA Repository

Spring Boot
Puzzle

Anotaciones y mapeo en JPA

Spring Boot
Puzzle

Integración con Vue

Spring Boot
Test

Consultas JPQL con @Query en Spring Data JPA

Spring Boot
Test

Open API y cómo agregarlo en Spring Boot

Spring Boot
Puzzle

Uso de Controladores REST

Spring Boot
Puzzle

API Specification

Spring Boot
Puzzle

Inyección de dependencias

Spring Boot
Test

Introducción a Spring Boot

Spring Boot
Test

Consultas JPQL con @Query en Spring Data JPA

Spring Boot
Puzzle

API Query By Example (QBE)

Spring Boot
Puzzle

Inyección de dependencias

Spring Boot
Código

Vista en Spring MVC con Thymeleaf

Spring Boot
Test

Servicios en Spring

Spring Boot
Código

Configuración de Vue

Spring Boot
Puzzle

Integración con Angular

Spring Boot
Test

API Query By Example (QBE)

Spring Boot
Test

API Specification

Spring Boot
Test

Controladores MVC

Spring Boot
Test

Métodos find en repositorios

Spring Boot
Test

Repositorios Spring Data

Spring Boot
Test

Inyección de dependencias

Spring Boot
Puzzle

Data JPA y Mail Starters

Spring Boot
Test

Configuración de Angular

Spring Boot
Puzzle

Controladores Spring REST

Spring Boot
Test

Configuración de Controladores MVC

Spring Boot
Puzzle

Asociaciones de entidades JPA

Spring Boot
Código

Actualizar datos de base de datos

Spring Boot
Test

Identificadores y relaciones JPA

Spring Boot
Puzzle

Verificar token JWT en peticiones

Spring Boot
Test

Login de usuarios

Spring Boot
Test

Integración con React

Spring Boot
Test

Configuración de React

Spring Boot
Puzzle

Asociaciones en JPA

Spring Boot
Test

Consultas JPQL

Spring Boot
Código

Todas las lecciones de SpringBoot

Accede a todas las lecciones de SpringBoot y aprende con ejemplos prácticos de código y ejercicios de programación con IDE web sin instalar nada.

Introducción A Spring Boot

Spring Boot

Introducción Y Entorno

Spring Boot Starters

Spring Boot

Introducción Y Entorno

Inyección De Dependencias

Spring Boot

Introducción Y Entorno

Controladores Spring Mvc

Spring Boot

Spring Web

Vista En Spring Mvc Con Thymeleaf

Spring Boot

Spring Web

Controladores Spring Rest

Spring Boot

Spring Web

Open Api Y Cómo Agregarlo En Spring Boot

Spring Boot

Spring Web

Servicios En Spring

Spring Boot

Spring Web

Crear Entidades Jpa

Spring Boot

Persistencia Con Spring Data

Asociaciones De Entidades Jpa

Spring Boot

Persistencia Con Spring Data

Repositorios Spring Data

Spring Boot

Persistencia Con Spring Data

Métodos Find En Repositorios

Spring Boot

Persistencia Con Spring Data

Inserción De Datos

Spring Boot

Persistencia Con Spring Data

Actualizar Datos De Base De Datos

Spring Boot

Persistencia Con Spring Data

Borrar Datos De Base De Datos

Spring Boot

Persistencia Con Spring Data

Consultas Jpql Con @Query En Spring Data Jpa

Spring Boot

Persistencia Con Spring Data

Api Query By Example (Qbe)

Spring Boot

Persistencia Con Spring Data

Repositorios Reactivos

Spring Boot

Persistencia Con Spring Data

Api Specification

Spring Boot

Persistencia Con Spring Data

Integración Con React

Spring Boot

Integración Frontend

Integración Con Vue

Spring Boot

Integración Frontend

Integración Con Angular

Spring Boot

Integración Frontend

Registro De Usuarios

Spring Boot

Seguridad Con Spring Security

Login De Usuarios

Spring Boot

Seguridad Con Spring Security

Verificar Token Jwt En Peticiones

Spring Boot

Seguridad Con Spring Security

Accede GRATIS a SpringBoot y certifícate

En esta lección

Objetivos de aprendizaje de esta lección

  1. Comprender cómo Spring MVC estructura una aplicación web y cómo se integra con Thymeleaf para generar vistas.
  2. Aprender a configurar Thymeleaf en un proyecto Spring Boot y personalizar la configuración si es necesario.
  3. Aprender a crear y utilizar plantillas Thymeleaf, incluyendo el uso de la sintaxis de Thymeleaf para enlazar datos del modelo en las vistas.
  4. Comprender cómo Spring Boot facilita la integración con Thymeleaf a través de la autoconfiguración y otras características.
  5. Adquirir una visión general de cómo estas tecnologías pueden utilizarse juntas para desarrollar aplicaciones web efectivas.