Thymeleaf is a template engine which exercises the HTML or XML file, parses it and then produces web content.
The primary difference between JSP and thymeleaf is JSPs compile to Servlets.
However, Thymeleaf reads the template file, parses its DOM and then applies the model to it.
In this tutorial, we will take a look at how to use thymeleaf in spring boot application.
More Spring Boot tutorials
Spring Boot Security Example.
Spring Validator
Spring Boot REST Example
Spring Boot Swagger 2 Example
Features of Thymeleaf
1. Integration with Spring is easy
2. Simple to use.
3. Support Spring Expression Language (SpEL)
4. Integration with Spring Security is easy
5. Cache support
6. Internationalization support
Let’s develop a demo using the Spring Boot web and Thymeleaf.
Thymeleaf configuration
At first, let’s see how to configure thymeleaf into spring boot.
Let’s create a new project in Spring Tool Suite 4 and add dependencies for Web and Thymeleaf dependencies.
Adding thymeleaf in spring boot is easy. You don’t have to perform any configuration. Just adding spring-boot-starter-thymeleaf in pom.xml is sufficient.
<?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 http://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.1.6.RELEASE</version> <relativePath /> <! – lookup parent from repository --> </parent> <groupId>com.codedelay</groupId> <artifactId>spring-boot-thymeleaf-demo</artifactId> <version>0.0.1-SNAPSHOT</version> <name>spring-boot-thymeleaf-demo</name> <description>Demo project for Spring Boot Thymeleaf</description> <properties> <java.version>1.8</java.version> <maven-jar-plugin.version>3.1.1</maven-jar-plugin.version> </properties> <dependencies> <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>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>
Project’s dependency tree
[INFO] - – maven-dependency-plugin:3.1.1:tree (default-cli) @ spring-boot-thymeleaf-demo – - [INFO] com.codedelay:spring-boot-thymeleaf-demo:jar:0.0.1-SNAPSHOT [INFO] +- org.springframework.boot:spring-boot-starter-thymeleaf:jar:2.1.6.RELEASE:compile [INFO] | +- org.springframework.boot:spring-boot-starter:jar:2.1.6.RELEASE:compile [INFO] | | +- org.springframework.boot:spring-boot-starter-logging:jar:2.1.6.RELEASE:compile [INFO] | | | +- ch.qos.logback:logback-classic:jar:1.2.3:compile [INFO] | | | | \- ch.qos.logback:logback-core:jar:1.2.3:compile [INFO] | | | +- org.apache.logging.log4j:log4j-to-slf4j:jar:2.11.2:compile [INFO] | | | | \- org.apache.logging.log4j:log4j-api:jar:2.11.2:compile [INFO] | | | \- org.slf4j:jul-to-slf4j:jar:1.7.26:compile [INFO] | | +- javax.annotation:javax.annotation-api:jar:1.3.2:compile [INFO] | | \- org.yaml:snakeyaml:jar:1.23:runtime [INFO] | +- org.thymeleaf:thymeleaf-spring5:jar:3.0.11.RELEASE:compile [INFO] | | +- org.thymeleaf:thymeleaf:jar:3.0.11.RELEASE:compile [INFO] | | | +- org.attoparser:attoparser:jar:2.0.5.RELEASE:compile [INFO] | | | \- org.unbescape:unbescape:jar:1.1.6.RELEASE:compile [INFO] | | \- org.slf4j:slf4j-api:jar:1.7.26:compile [INFO] | \- org.thymeleaf.extras:thymeleaf-extras-java8time:jar:3.0.4.RELEASE:compile [INFO] +- org.springframework.boot:spring-boot-starter-web:jar:2.1.6.RELEASE:compile [INFO] | +- org.springframework.boot:spring-boot-starter-json:jar:2.1.6.RELEASE:compile [INFO] | | +- com.fasterxml.jackson.core:jackson-databind:jar:2.9.9:compile [INFO] | | | +- com.fasterxml.jackson.core:jackson-annotations:jar:2.9.0:compile [INFO] | | | \- com.fasterxml.jackson.core:jackson-core:jar:2.9.9:compile [INFO] | | +- com.fasterxml.jackson.datatype:jackson-datatype-jdk8:jar:2.9.9:compile [INFO] | | +- com.fasterxml.jackson.datatype:jackson-datatype-jsr310:jar:2.9.9:compile [INFO] | | \- com.fasterxml.jackson.module:jackson-module-parameter-names:jar:2.9.9:compile [INFO] | +- org.springframework.boot:spring-boot-starter-tomcat:jar:2.1.6.RELEASE:compile [INFO] | | +- org.apache.tomcat.embed:tomcat-embed-core:jar:9.0.21:compile [INFO] | | +- org.apache.tomcat.embed:tomcat-embed-el:jar:9.0.21:compile [INFO] | | \- org.apache.tomcat.embed:tomcat-embed-websocket:jar:9.0.21:compile [INFO] | +- org.hibernate.validator:hibernate-validator:jar:6.0.17.Final:compile [INFO] | | +- javax.validation:validation-api:jar:2.0.1.Final:compile [INFO] | | +- org.jboss.logging:jboss-logging:jar:3.3.2.Final:compile [INFO] | | \- com.fasterxml:classmate:jar:1.4.0:compile [INFO] | +- org.springframework:spring-web:jar:5.1.8.RELEASE:compile [INFO] | | \- org.springframework:spring-beans:jar:5.1.8.RELEASE:compile [INFO] | \- org.springframework:spring-webmvc:jar:5.1.8.RELEASE:compile [INFO] | +- org.springframework:spring-aop:jar:5.1.8.RELEASE:compile [INFO] | +- org.springframework:spring-context:jar:5.1.8.RELEASE:compile [INFO] | \- org.springframework:spring-expression:jar:5.1.8.RELEASE:compile [INFO] +- org.springframework.boot:spring-boot-devtools:jar:2.1.6.RELEASE:runtime (optional) [INFO] | +- org.springframework.boot:spring-boot:jar:2.1.6.RELEASE:compile [INFO] | \- org.springframework.boot:spring-boot-autoconfigure:jar:2.1.6.RELEASE:compile [INFO] \- org.springframework.boot:spring-boot-starter-test:jar:2.1.6.RELEASE:test [INFO] +- org.springframework.boot:spring-boot-test:jar:2.1.6.RELEASE:test [INFO] +- org.springframework.boot:spring-boot-test-autoconfigure:jar:2.1.6.RELEASE:test [INFO] +- com.jayway.jsonpath:json-path:jar:2.4.0:test [INFO] | \- net.minidev:json-smart:jar:2.3:test [INFO] | \- net.minidev:accessors-smart:jar:1.2:test [INFO] | \- org.ow2.asm:asm:jar:5.0.4:test [INFO] +- junit:junit:jar:4.12:test [INFO] +- org.assertj:assertj-core:jar:3.11.1:test [INFO] +- org.mockito:mockito-core:jar:2.23.4:test [INFO] | +- net.bytebuddy:byte-buddy:jar:1.9.13:test [INFO] | +- net.bytebuddy:byte-buddy-agent:jar:1.9.13:test [INFO] | \- org.objenesis:objenesis:jar:2.6:test [INFO] +- org.hamcrest:hamcrest-core:jar:1.3:test [INFO] +- org.hamcrest:hamcrest-library:jar:1.3:test [INFO] +- org.skyscreamer:jsonassert:jar:1.5.0:test [INFO] | \- com.vaadin.external.google:android-json:jar:0.0.20131108.vaadin1:test [INFO] +- org.springframework:spring-core:jar:5.1.8.RELEASE:compile [INFO] | \- org.springframework:spring-jcl:jar:5.1.8.RELEASE:compile [INFO] +- org.springframework:spring-test:jar:5.1.8.RELEASE:test [INFO] \- org.xmlunit:xmlunit-core:jar:2.6.2:test [INFO] \- javax.xml.bind:jaxb-api:jar:2.3.1:test [INFO] \- javax.activation:javax.activation-api:jar:1.2.0:test [INFO] – ----------------------------------------------------------------------

As you could see that spring automatically downloaded Thymeleaf 3.0.11
version into the project’s classpath.
In addition to that when spring boot finds the thymeleaf jars in the classpath, then it automatically processes and configures it with default properties.
In order to change configuration properties, you can specify values in the application.properties or application.yml file.
If you want to use a specific version of thymeleaf then you can specify version details in the properties tag of pom.xml.
<thymeleaf.version>3.0.11.RELEASE</thymeleaf.version>
Important Thymeleaf Properties
Let’s take a look into a few important properties.
spring.thymeleaf.cache
: enable/disable template cachingspring.thymeleaf.prefix
: add the prefix name to the view name before building the URL.spring.thymeleaf.suffix
: add the suffix name to the view name before building the URL.spring.thymeleaf.check-template
: Before rendering, check whether the template exists or not.spring.thymeleaf.encoding
: Specifies the template encodingspring.thymeleaf.content-type
: Specifies the content type
Create Controller Class
A controller can handle the incoming request, prepares the model data and return the view (HTML) to render greet.html.
package com.codedelay.controller; import org.springframework.beans.factory.annotation.Value; import org.springframework.stereotype.Controller; import org.springframework.ui.Model; import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.RequestParam; @Controller public class GreetingController { @Value("${greeting.msg}") private String greetingMsg; ///greet?name="codedelay" @GetMapping("/greet") public String greet(@RequestParam(name = "name", required = false, defaultValue = "CodeDelay") String message, Model model) { model.addAttribute("message", message); return "greet"; } @GetMapping("/") public String home(Model model) { model.addAttribute("message", greetingMsg); return "greet"; } }
As you could notice from the above class GreetingController
is a Controller class that maps incoming HTTP GET request with a view.
The above GreetingController
class can process “/” and “/greet” request.
@GetMapping
maps /greet
to greet()
method.
In addition to that, the ‘name’ is a query string parameter of /greet
request.
Let’s take a look at the view template
View Template
Firstly create a greet.html in the src/main/resources
folder.
The below file is a simple HTML5 template with some thymeleaf related modifications.
greet.html
<!DOCTYPE HTML> <html lang="en" xmlns:th="http://www.thymeleaf.org"> <head> <meta charset="utf-8"> <meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no"> <meta name="description" th:content="${pagename}"> <meta name="author" content="${name}"> <title>Spring Boot Thymeleaf Example</title> <link rel="stylesheet" th:href="@{/main.css}" /> </head> <body> <nav class="navbar navbar-expand-md navbar-dark bg-dark fixed-top"> <a class="navbar-brand" href="#">Codedelay.com</a> </nav> <main role="main" class="container"> <div class="starter-template"> <h1>Spring Boot Thymeleaf Example</h1> <h2> <span th:text="'Hello, ' + ${message}"></span> </h2> </div> </main> </body> </html>
main.css
h2 { color: green; }
Now, let’s run this program to see the output.

