Generic Top

I just announced the new Learn Spring course, focused on the fundamentals of Spring 5 and Spring Boot 2:

>> CHECK OUT THE COURSE

1. Introduction

In this tutorial, we'll talk about different ways to access Spring MVC data using Thymeleaf.

We'll start by creating an email template using Thymeleaf, and we'll 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>
    <version>2.2.6.RELEASE</version>
</dependency>

Second, let's include the Spring Boot web starter:

<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-web</artifactId>
    <version>2.2.6.RELEASE</version>
</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 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>

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>

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 so we can pass data to our template.

As always, the code is available over on GitHub.

Generic bottom

I just announced the new Learn Spring course, focused on the fundamentals of Spring 5 and Spring Boot 2:

>> CHECK OUT THE COURSE
Comments are closed on this article!