1. Introduction
In this tutorial, we’ll discuss different ways to access Spring MVC data using Thymeleaf.
We’ll start by creating an email template using Thymeleaf and enhance it with data from our Spring application.
2. Project Setup
First, we’ll need to add our Thymeleaf dependency:
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-thymeleaf</artifactId>
</dependency>
Second, let’s include the Spring Boot web starter:
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
This dependency provides us with REST support that we’ll later use to create some endpoints.
We’ll create a few Thymeleaf templates to cover our example cases and store them in resources/mvcdata. Each section of the tutorial will implement a different template:
<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml" xmlns:th="http://www.thymeleaf.org">
<!-- data -->
</html>
Lastly, we’ll need to implement a controller class where we will store our business logic:
@Controller
public class EmailController {
private ServletContext servletContext;
public EmailController(ServletContext servletContext) {
this.servletContext = servletContext;
}
}
Our controller class won’t always depend on the servlet context, but we’re adding it here so we can demonstrate a specific Thymeleaf feature later on.
3. Model Attributes
Model attributes are used inside controller classes that prepare the data for rendering inside a view.
One way we can add attributes to our Model is to require an instance of the Model as a parameter in a controller method.
Let’s pass our emailData as an attribute:
@GetMapping(value = "/email/modelattributes")
public String emailModel(Model model) {
model.addAttribute("emailData", emailData);
return "mvcdata/email-model-attributes";
}
Spring will then inject an instance of Model for us when /email/modelattributes is requested.
Then, we can refer to our emailData model attribute in a Thymeleaf expression:
<p th:text="${emailData.emailSubject}">Subject</p>
Another way we can do it is by telling our Spring container what attribute is required in our view by using @ModelAttribute:
@ModelAttribute("emailModelAttribute")
EmailData emailModelAttribute() {
return emailData;
}
And then, we can represent the data in our view as:
<p th:each="emailAddress : ${emailModelAttribute.getEmailAddresses()}">
<span th:text="${emailAddress}"></span>
</p>
For more examples on Model data, please check out our Model, ModelMap, and ModelView in Spring MVC tutorial.
4. Request Parameters
Another way of accessing data is by request parameters:
@GetMapping(value = "/email/requestparameters")
public String emailRequestParameters(
@RequestParam(value = "emailsubject") String emailSubject) {
return "mvcdata/email-request-parameters";
}
Meanwhile, in our template, we’ll need to specify which parameter contains the data by using the keyword param:
<p th:text="${param.emailsubject}"></p>
We can also have multiple request parameters with the same name:
@GetMapping(value = "/email/requestparameters")
public String emailRequestParameters(
@RequestParam(value = "emailsubject") String emailSubject,
@RequestParam(value = "emailaddress") String emailAddress1,
@RequestParam(value = "emailaddress") String emailAddress2) {
return "mvcdata/email-request-parameters";
}
Then, we’ll have two options to show the data.
First, we can use th:each to go through each parameter with the same name:
<p th:each="emailaddress : ${param.emailaddress}">
<span th:text="${emailaddress}"></span>
</p>
Second, we can use the index of our parameter array:
<p th:text="${param.emailaddress[0]}"></p>
<p th:text="${param.emailaddress[1]}"></p>
5. Session Attributes
Or, we can place our data in an HttpSession attribute:
@GetMapping("/email/sessionattributes")
public String emailSessionAttributes(HttpSession httpSession) {
httpSession.setAttribute("emaildata", emailData);
return "mvcdata/email-session-attributes";
}
Then, similarly to request parameters, we can use the session keyword:
<p th:text="${session.emaildata.emailSubject}"></p>
It’s important to note here however that since Thymeleaf 3.1 the session object, among others, has been deprecated for security reasons.
The recommended alternative would be to add to your model, at the controller level, the specific pieces of information your templates need from these objects, stated here.
6. ServletContext Attributes
With ServletContext, we won’t be able to use an expression to access emailData‘s properties.
To work around this, we’ll pass each value as a separate attribute:
@GetMapping("/email/servletcontext")
public String emailServletContext() {
servletContext.setAttribute("emailsubject", emailData.getEmailSubject());
servletContext.setAttribute("emailcontent", emailData.getEmailBody());
servletContext.setAttribute("emailaddress", emailData.getEmailAddress1());
servletContext.setAttribute("emaillocale", emailData.getEmailLocale());
return "mvcdata/email-servlet-context";
}
And then, we can retrieve each via the servletContext variable:
<p th:text="${#servletContext.getAttribute('emailsubject')}"></p>
Similarly here, since Thymeleaf 3.1 the servletContext object, among others, has been deprecated for security reasons.
7. Beans
Finally, we can also provide data using context beans:
@Bean
public EmailData emailData() {
return new EmailData();
}
Thymeleaf allows bean access using @beanName syntax:
<p th:text="${@emailData.emailSubject}"></p>
8. Conclusion
In this small tutorial, we learned how to access data through Thymeleaf.
First, we added the proper dependencies. And second, we implemented some REST methods to pass data to our template.
As always, the code is available on GitHub.