Using Thymeleaf with Spring

Last updated : Jul 30, 2023 12:00 AM

Thymeleaf is a Java library that works as a template engine for both server-side and standalone environments. Thymeleaf implements the concept of Natural Templates, i.e. templates that can be opened and viewed in web browsers while maintaining the correct markup structure as they would be accessed in a server-side deployed environment. This Natural Templates concept makes the development process fast and less complicated. In simple words, Thymeleaf templates are simple html files that can be styled, scripted, and viewed as they are without being deployed on a server. This is not true with JSP technology.

Thymeleaf can process and generate HTML, XML, JavaScript, CSS, and text. Thymeleaf templates can be used to completely replace JSP technology. In this example, we will create a simple web application with spring and use Thymeleaf as the view layer.

Getting started with Thymeleaf is simple and straight forward. If you have a project set up and ready to go, feel free to skip to Integrating Thymeleaf with Spring section to add Thymeleaf template support to your project.

Creating a Web Project

If you are starting from scratch, now it is time to create a project to host our Thymeleaf templates. Follow this tutorial to create a simple maven web project.

Integrating Spring with Maven webapp

The above tutorial creates a maven web app without Spring integration. Let's introduce the spring framework to the webapp before integrating with Thymeleaf.

Do the below changes to pom.xml to include the necessary Spring libraries to the classpath. Replace ${spring.version} with the Spring framework version that you work with.

pom.xmlDescription
<dependency>
   <groupId>org.springframework</groupId>
   <artifactId>spring-core</artifactId>
   <version>${spring.version}</version>
</dependency>
<dependency>
   <groupId>org.springframework</groupId>
   <artifactId>spring-webmvc</artifactId>
   <version>${spring.version}</version>
</dependency>

In the above code, we introduce bare minimum spring capabilities to our project to work with Thymeleaf templating engine. Note the line spring-webmvc. When we progress further in this tutorial, we will see how to inject Thymeleaf as our view layer.

To define spring specific configuration, we will create an XML file called applicationContext.xml in the WEB-INF folder.

If you named this file something other than applicationContext.xml, you will have to explicitly define it in the web.xml file. So to keep it simple, name the file as applicationContext.xml. We will come back to this file later.

Integrating Thymeleaf with Spring

Now we have created a spring web app in the above steps. Now, we have to include Thymeleaf dependencies in the same Maven POM file we referred to earlier. Make sure to select the compatible Thymeleaf version with the Spring version that you work with.

pom.xmlDescription
<dependency>
   <groupId>org.thymeleaf</groupId>
   <artifactId>thymeleaf-spring4</artifactId>
   <version>3.0.9.RELEASE</version>
</dependency>

The next step is to tell Spring that we want to use Thymeleaf as the view resolver. Now, let's refer back to the applicationContext.xml file we have created. The below code snippet shows how to instantiate Thymeleaf in applicationContext.

applicationContextDescription
<bean id="templateResolver" class="org.thymeleaf.templateresolver.ServletContextTemplateResolver">
    <property name="prefix" value="/WEB-INF/views/" />
    <property name="suffix" value=".html" />
    <property name="templateMode" value="HTML5" />
    <property name="cacheable" value="false" />
</bean>
<bean id="templateEngine" class="org.thymeleaf.spring4.SpringTemplateEngine">
    <property name="templateResolver" ref="templateResolver" />
</bean>
<bean class="org.thymeleaf.spring4.view.ThymeleafViewResolver">
    <property name="templateEngine" ref="templateEngine" />
</bean>

The bean templateResolver defines Thymeleaf template specific configurations. The org.thymeleaf.templateresolver.ServletContextTemplateResolver is customizable. It accepts four properties which are explained below.

  • Prefix - The base folder our templates reside
  • Suffix - The file formats we give to our templates
  • templateMode - This variable tells what template type to generate and validate code against. In our case, HTML5. Other options are TEXT, JAVASCRIPT, etc...
  • cacheable - If set to true, stores a pre-parsed version of Thymeleaf templates for improved performance.

Creating Thymeleaf templates

According to the above settings, our Thymeleaf templates should reside in the/ WEB-INF/views folder. The template file extension is html and templates are parsed and validated against htnl5 syntax.

Please note that cacheable should be set to true (or remove the entry) in the production environment. Setting this to false enables us to hot deploy Thymeleaf template specific changes without restarting the server.

Now we are all set to use Thymeleaf. Let's create a simple page with a header, content, and footer. Note that even we create 3 separate files for header, content, footer, we also can include them in a single Html file defined as 3 separate fragments.

HContent for page headerDescription
<!doctype html>
<html lang="en" xmlns="https://www.w3.org/1999/xhtml" xmlns:th="https://www.thymeleaf.org">
<body>
  <div th:fragment="header1">
    Page Header
  </div>
</body>
</html>

/WEB-INF/views/header.html Content for page header

Content for page contentDescription
<!doctype html>
<html lang="en" xmlns="https://www.w3.org/1999/xhtml" xmlns:th="https://www.thymeleaf.org">
<body>
  <div th:fragment="content1">
    Page Content
  </div>
</body>
</html>

/WEB-INF/views/content.html Content for page content

Content for page footerDescription
<!doctype html>
<html lang="en" xmlns="https://www.w3.org/1999/xhtml" xmlns:th="https://www.thymeleaf.org">
<body>
  <div th:fragment="footer1">
    Page Footer
  </div>
</body>
</html>

/WEB-INF/views/footer.html Content for page footer

xmlns:th="https://www.thymeleaf.org" plays an important role here. xmlns stands for xml namespace. It contains all the definitions we use within this html template. For example, th:fragment is defined in xmlns.

Note that thymeleaf extracts the contents defined as fragments. Therefore, we extract html for header, content, and footer from these templates and display it as html. Now, let's create another template to put all three templates together.

Html Template to put header, content and footer templates togetherDescription
<!doctype html>
<html lang="en" xmlns="https://www.w3.org/1999/xhtml" xmlns:th="https://www.thymeleaf.org">
<body>
	<div th:replace="header::header1">
	<div th:replace="content::content1">
	<div th:replace="footer::footer1">
</body>
</html>

/WEB-INF/views/home.html Template to put header, content and footer templates together.

Here, we refer the three templates we created earlier. When we specify th:replace="header::header1, Thymeleaf looks for the file named header.html and the fragment header1 within header.html, and th:replace will replace the calling div with the fragment content. Note that suffix we defined in applicationContext.xml is used to detemine the file to obtain the fragment from. In this case, header + suffix. Make sure to pay attention to the file location. For an example, if you placed the header.html in folder headers, your reference should look like

. Same applies to all fragments being injected. The prefix we defined in applicationContext.xml is used to look up the path.

Creating a Spring controller

Finally, it's time to call the template from a controller. Create a controller and simply forward the request to the template like below.

Spring controllerDescription
@Controller
public class EstimateController{
   @RequestMapping(value = "/home", method = RequestMethod.GET)
      public String home(HttpServletRequest request)
      {
         return "home";
      }
}

The controller returns a string. When it returns, our templateResolver defined in springContext.xml kicks in and start assembling our view component. The equation is like:

view to show = prefix + method return value + suffix which translates to /WEB-INF/views/ + home + .html

The qualified resource is our html file that ties the header, content, and footer together. This generated content is validated against html5 and not cached. Any changes done to Thymeleaf templates during the server is run would affect immediately and reflect in the output. Visit https://localhost:8080/{ProjectName}/home to view the response generated by the Thymeleaf template. Replace {ProjectName} with your actual webapp name.

Lance

By: Lance

Hi, I'm Lance Raney, a dedicated Fullstack Developer based in Oklahoma with over 15 years of exp

Read more...