Thymeleaf Template Engine: A Comprehensive Guide

Overview

Thymeleaf is a modern server-side Java template engine that processes HTML, XML, JavaScript, CSS, and plain text. Unlike traditional templating engines, Thymeleaf can process templates in both web and non-web environments. It uses natural templates that function as static prototypes, enabling seamless collaboration between designers and developers.

The core parsing layer relies on Attoparser, a high-performance event-based parser. Natural templates written with Thymeleaf syntax remain valid and viewable in browsers without server-side processing, making development and debugging more straightforward.


Spring Boot Integration

Setting up Thymeleaf in a Spring Boot application requires minimal configuration. Add the following dependencies to your project's build file:

<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.mybatis.spring.boot</groupId>
    <artifactId>mybatis-spring-boot-starter</artifactId>
    <version>2.1.1</version>
</dependency>

Configuration Properties

server:
  port: 8088

spring:
  thymeleaf:
    cache: false
    mode: HTML
    encoding: UTF-8
  
  datasource:
    driver-class-name: com.mysql.cj.jdbc.Driver
    url: jdbc:mysql://localhost:3306/appdb?serverTimezone=Asia/Shanghai&useUnicode=true&characterEncoding=utf8&useSSL=false
    username: root
    password: password
    hikari:
      minimumIdle: 10
      maximumPoolSize: 10
      connectionTimeout: 60000
      idleTimeout: 60000
      maxLifeTime: 60000
      connectionTestQuery: SELECT 1

  redis:
    host: localhost
    port: 6379
    timeout: 10s
    lettuce:
      pool:
        min-idle: 4
        max-idle: 10
        max-active: 10
        max-wait: -1ms

mybatis:
  mapper-locations: classpath*:mapper/*Mapper.xml

The cache: false setting disables template caching during development, enabling immediate reflection of changes without restarting the application.


Spring Security Integration

When combining Thymeleaf with Spring Secuirty, include the Security extras dependency to access authentication and authorization context in templates:

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

<dependency>
    <groupId>org.thymeleaf.extras</groupId>
    <artifactId>thymeleaf-extras-springsecurity5</artifactId>
</dependency>

Declare the namespace in your template files:

<html xmlns:th="http://www.thymeleaf.org"
      xmlns:sec="http://www.thymeleaf.org/extras/spring-security">

Access the authenticated user's data using the authentication object:

<div sec:authentication="principal.username"></div>
<div th:each="item : ${#authentication.principal.menus}">
    <span th:text="${item.name}"></span>
</div>


Expresssion Syntax

Thymeleaf provides two types of inline expressions for output:

Escaped Output: [[...]]

The double-bracket syntax escapes HTML content, treating special characters as literal text:

<span>[[${message}]]</span>

If message contains <b>Hello</b>, the browser renders it as plain text rather than bold formatting.

Unescaped Output: [(...)]

The single-bracket with parentheses syntax outputs raw HTML without escaping:

<span th:text="${message}">[[${message}]]</span>
<span th:utext="${message}">[(${message})]</span>

Use th:utext (unescaped text) when you intentional want to render HTML markup:

<!-- When message contains "<b>Hello</b>" -->
<th:block th:utext="${message}"></th:block>
<!-- Output: Hello (rendered as bold) -->


Common Template Attributes

Text Rendering

<!-- Escaped output -->
<p th:text="${userInput}"></p>

<!-- Unescaped output -->
<p th:utext="${userInput}"></p>

Iteration with th:each

Loop through collections to generate repeated elements:

<ul>
    <li th:each="item : ${items}" 
        th:class="${item.active} ? 'active' : ''"
        th:text="${item.label}">
    </li>
</ul>

Access loop status using iteration status variables:

<tr th:each="row, status : ${rows}">
    <td th:text="${status.index + 1}"></td>
    <td th:text="${row.name}"></td>
    <td th:text="${status.even} ? 'Yes' : 'No'"></td>
</tr>

Date Formatting

Format date objects using the #dates utility:

<span th:text="${#dates.format(record.createdAt, 'yyyy-MM-dd HH:mm:ss')}"></span>

<!-- Custom format -->
<span th:text="${#temporals.format(order.date, 'dd/MM/yyyy')}"></span>

Dynamic Attributes

Set dynamic attributes using th:attr:

<button th:attr="data-id=${item.id}, data-action=${item.action}">
    Process
</button>

<!-- Conditional class application -->
<div th:class="${condition} ? 'enabled' : 'disabled'">
    Content
</div>


Conclusion

Thymeleaf's natural templating approach simplifies Java web development by allowing templates to function as static design prototypes. The extensive expression language, Spring Security integration, and flexible attribute system make it a powerful choice for modern web applications. Understanding the distinction between escaped and unescaped output is crucial for preventing XSS vulnerabilities while maintaining template flexibility.

Tags: thymeleaf spring-boot spring-mvc template-engine spring-security

Posted on Fri, 22 May 2026 23:05:17 +0000 by thenature4u