Spring Boot Model

Spring Boot Model tutorial shows how to work with a model in a Spring Boot application. The model is represented by Model, ModelMap, and ModelAndView in Spring.

Spring is a popular Java application framework and Spring Boot is an evolution of Spring that helps create stand-alone, production-grade Spring based applications easily.

MVC

MVC (Model-View-Controller) is a software architecture pattern, which separates application into three parts: model, view, and controller. The model represents a Java object carrying data. The view visualizes the data that the model contains. The controller manages the data flow into model object and updates the view whenever data changes; it keeps view and model separate.

Spring MVC

Spring MVC is the original web framework built on the Servlet API. It is build on the MVC design pattern. Spring Framework 5.0 introduced a parallel reactive stack web framework called Spring WebFlux.

Model, ModelMap, ModelAndView

Model, ModelMap, and ModelAndView are used to define a model in a Spring MVC application. Model defines a holder for model attributes and is primarily designed for adding attributes to the model. ModelMap is an extension of Model with the ability to store attributes in a map and chain method calls. ModelAndView is a holder for a model and a view; it allows to return both model and view in one return value.

Spring Boot Model example

The following simple web application uses Model, ModelMap, and ModelAndView in the controller methods. The model holds application data, which is displayed in the view. We use the Freemaker library for the view layer.

$ tree
.
├── pom.xml
└── src
    ├── main
    │   ├── java
    │   │   └── com
    │   │       └── zetcode
    │   │           ├── Application.java
    │   │           └── controller
    │   │               └── MyController.java
    │   └── resources
    │       ├── application.properties
    │       ├── static
    │       │   └── index.html
    │       └── templates
    │           └── show.ftl
    └── test
        └── java

This is the project structure of the Spring application.

pom.xml
<?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>
    <groupId>com.zetcode</groupId>
    <artifactId>SpringBootModel</artifactId>
    <version>1.0-SNAPSHOT</version>
    <packaging>jar</packaging>
    
    <properties>
        <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
        <maven.compiler.source>1.8</maven.compiler.source>
        <maven.compiler.target>1.8</maven.compiler.target>
    </properties>
    
    <parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>1.5.9.RELEASE</version>
    </parent>

    <dependencies>
        
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-freemarker</artifactId>
        </dependency>   
        
    </dependencies>

    <build>
        <plugins>
            <plugin>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-maven-plugin</artifactId>
            </plugin>
        </plugins>
    </build>       
    
</project>

This is the Maven pom.xml file. The spring-boot-starter-parent is a parent POM providing dependency and plugin management for applications built with Maven. The spring-boot-starter-freemarker is a dependency for the Freemarker template engine. This dependency will also have the Spring MVC included in the project. The spring-boot-maven-plugin packages Spring applications into executable JAR or WAR archives.

application.properties
server.port=8086
server.contextPath=/myapp

spring.main.banner-mode=off
logging.level.org.springframework=ERROR

mymessage=Hello there

The application.properties is the main configuration file in Spring Boot. We set the server port and context path, turn off the Spring banner, and reduce the amount of logging of the Spring framework by selecting only error messages. The mymessage property contains the message.

MyController.java
package com.zetcode.controller;

import java.time.LocalDateTime;
import java.time.ZoneId;
import java.time.format.DateTimeFormatter;
import java.time.format.FormatStyle;
import java.util.Locale;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.ui.ModelMap;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.servlet.ModelAndView;

@Controller
public class MyController {
    
    @Value("${mymessage}")
    private String message;
    
    @GetMapping("/getMessage")
    public String getMessage(Model model) {
        
        model.addAttribute("message", message);
        
        return "show";
    }
    
    @GetMapping("/getMessage2")
    public ModelAndView getMessage() {
        
        ModelAndView mav = new ModelAndView();
        mav.addObject("message", message);
        mav.setViewName("show");
        
        return mav;
    }
    
    @GetMapping("/getMessageAndTime")
    public String getMessageAndTime(ModelMap map) {
        
        LocalDateTime ldt = LocalDateTime.now();
        
        DateTimeFormatter fmt = DateTimeFormatter.ofLocalizedDateTime(
                FormatStyle.MEDIUM);
        fmt.withLocale(new Locale("sk", "SK"));
        fmt.withZone(ZoneId.of("CET"));
        String time = fmt.format(ldt);
        
        map.addAttribute("message", message).addAttribute("time", time);
        
        return "show";
    }
}

This is MyController. It has three methods that respond to client requests.

@Controller
public class MyController {

MyController is annotated with the @Controller annotation.

@Value("${mymessage}")
private String message;

With the @Value annotation, we insert the mymessage property from the application.properties file into the message attribute.

@GetMapping("/getMessage")
public String getMessage(Model model) {
    
    model.addAttribute("message", message);
    
    return "show";
}

The @GetMapping maps the /getMessage URL pattern to the getMessage() method. In the getMessage() method, we use the Model. It receives a message attribute with the addAttribute() method. The return keyword returns the name of the view, which will be resolved to show.ftl, because we use the Freemarker template system.

@GetMapping("/getMessage2")
public ModelAndView getMessage() {
    
    ModelAndView mav = new ModelAndView();
    mav.addObject("message", message);
    mav.setViewName("show");
    
    return mav;
}

In the second case, we use the ModelAndView. We use addObject() and setViewName() to add the model data and the view name. The method returns ModelAndView object.

@GetMapping("/getMessageAndTime")
public String getMessageAndTime(ModelMap map) {
    
    LocalDateTime ldt = LocalDateTime.now();
    
    DateTimeFormatter fmt = DateTimeFormatter.ofLocalizedDateTime(FormatStyle.MEDIUM);
    fmt.withLocale(new Locale("sk", "SK"));
    fmt.withZone(ZoneId.of("CET"));
    String time = fmt.format(ldt);
    
    map.addAttribute("message", message).addAttribute("time", time);
    
    return "show";
}

In the getMessageAndTime() method, we use ModelMap. The model map receives two attributes: message and time.

index.html
<!DOCTYPE html>
<html>
    <head>
        <title>Home page</title>
        <meta charset="UTF-8"/>
        <meta name="viewport" content="width=device-width, initial-scale=1.0"/>
    </head>
    <body>
        <ul>
            <li><a href="getMessage.html">Get message</a></li>
            <li><a href="getMessage2.html">Get message 2</a></li>
            <li><a href="getMessageAndTime.html">Get message and time</a></li>
        </ul>
    </body>
</html>

This is the home page. It contains three links that call the Spring controller methods. It is a static resource and is located in the predefined src/main/resources/static directory.

show.ftl
<!DOCTYPE html>
<html>
    <head>
        <title>Message</title>
        <meta charset="UTF-8">
        <meta name="viewport" content="width=device-width, initial-scale=1.0">
    </head>
    <body>
        <p>
            Message: ${message}
        </p>
        
        <#if time??>
            <p>Date and time: ${time}</p>
        </#if>
        
    </body>
</html>

The show.ftl is a Freemarker template file. It is located in the predefined src/main/resources/templates directory. It outputs the message and optionally the time with the ${} syntax.

Application.java
package com.zetcode;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;

@SpringBootApplication
public class Application  {
    
    public static void main(String[] args) {
        SpringApplication.run(Application.class, args);
    }
}

Application is the entry point which sets up Spring Boot application. The @SpringBootApplication annotation enables auto-configuration and component scanning. During the scanning process, the @Controller annotation is looked up and a Spring bean is created from the MyController class.

$ mvn spring-boot:run

After we start the application, we navigate to localhost:8086/myapp/.

In this tutorial, we have have worked with a model in a Spring application. You might also be interested in the related tutorials: Spring Boot @ModelAttribute tutorial, Spring Boot @Controller tutorial, Spring Boot Freemaker tutorial, Spring Boot @Component tutorial, Spring Boot @RequestParam tutorial, Java tutorial.