What You'll Learn

If you're following the tutorials in order, you will now have a simple controller serving static content dynamically.

In this tutorial, we are going to return HTML that changes with each request. We will show that it is dynamic by showing the current date and time.

You will recall that we implemented the Controller (the @Controller component) and the View (the template) elements of the MVC pattern in the previous tutorial. We will now include the Model part.

Some will argue that Spring's use of MVC is different to the original description of MVC. In the original description, the model is more akin to the domain model. That is, it is a model of the domain that the application is serving. The controller's job is to tell the model to update itself, and then direct the user to the next view. The view gets its data directly from the model - that is, it is akin to a portal onto the current state of the domain.

In Spring MVC, the model is a packaged portion of the domain that the controller pulls from the domain in order to serve the next view.

Due to this difference, we will use Spring's interpretation of ‘model' and we will refer to the application's core as the ‘domain'. As we will see later, it is still important to separate the handling of the request from the domain.

@GetMapping({"/", "index"})
    public String home(Model model) {
        model.addAttribute("today", LocalDate.now());
        return "index.html";
    }

Let's note a few things about this.

The model parameter

At the moment, we're not passing any parameters over the request, so the only parameter is a Model.

Where did that object come from?

This class is provided by Spring and is injected automatically for us. This is our first exposure to Dependency Injection. We will see a lot more of this later - but basically, in Spring, we inject dependencies rather than create them. Since we are using Spring MVC, Spring has capability to construct a Model object and provide it to us. Spring can also work out what parameters are expected and provide the required objects.

The Model class allows the controller to bundle a set of objects that can be passed to the view.

The method code

The new line of code in the method is:

model.addAttribute("today", LocalDate.now());

Amend the templates

Make a small change to the template.

<span>Welcome to Charity Giving.  Today is </span><span th:text="${today}"></span>

This looks like standard HTML, but there is a th:text attribute on the 2nd span element. This is a Thymeleaf tag and we included Thymeleaf support in our dependencies when we created the project.

If you didn't add Thymeleaf, add this line to the dependencies block in build.gradle.

implementation 'org.springframework.boot:spring-boot-starter-thymeleaf'

Thymeleaf is a templating engine. This attribute will replace the content of the element with the value of a object that is on the model (which Spring implicitly passes from the controller to the view). The template selects the required object by key, hence the syntax ${today}.

Natural templating

Thymeleaf has the advantage that you can populate the content in the template and preview it as a static page with dummy content. This is known as "Natural Templating". Only when run through Spring Boot will the dummy data be replaced by data from the model. To see this in action, put some static data in the span containing the Thymelead attribute (e.g. 25/12/2021 12:00). You should be able to preview this as a normal HTML file.

To test this, run gradle > build > classes again and then go to http://localhost:8080/charities.

In this tutorial, we've concluded the introduction of all of the parts of the MVC pattern. The MVC is a good example of "separation of concern". Take time to read around this idea. Have you seen another example of this within this tutorial?