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.