Spring Boot FreeMarker Example Tutorial

In Spring Boot FreeMarker tutorial we are going to create a simple Spring Boot web application with FreeMarker template engine and H2 database.

H2 Database

H2 is an open-source relational database management system created entirely in Java. It can be embedded in Java applications or run in the client-server mode. It is easy to deploy and install and has a small footprint.
        <dependency>
            <groupId>com.h2database</groupId>
            <artifactId>h2</artifactId>
            <scope>runtime</scope>
        </dependency>

FreeMarker

FreeMarker is a server-side Java template engine for both web and standalone environments. Templates are written in the FreeMarker Template Language (FTL), which is a simple, specialized language.
Read more about FreeMarker at official site - https://freemarker.apache.org/.
Here is a Spring boot starter for Freemarker:
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-freemarker</artifactId>
        </dependency>

Tools and Technologies used

  1. Spring Boot 2+
  2. Maven 3+
  3. STS or Eclipse IDE
  4. Freemarker
  5. JDK 8+ or OpenJDK 8+
  6. H2 Database
  7. Hibernate - 5.2.17.Final

Development Steps

  1. Create a Spring Boot Application
  2. Maven Dependencies
  3. Project Structure
  4. JPA Entity - Employee.java
  5. JPA Repository - EmployeeRepository.java
  6. Define Spring Controller - EmployeeController.java
  7. Define View Templates
  8. Run Application
  9. Demo

1. Create a Spring Boot Application

There are many ways to create a Spring Boot application. You can refer below articles to create a Spring Boot application.

2. Maven Dependencies

Add required maven depenedencies to 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>net.guides.springboot2</groupId>
    <artifactId>springboot2-freemarker-example</artifactId>
    <version>0.0.1-SNAPSHOT</version>
    <packaging>jar</packaging>
    <name>springboot2-freemarker-example</name>
    <parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>2.0.5.RELEASE</version>
        <relativePath />
        <!-- lookup parent from repository -->
    </parent>
    <properties>
        <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
        <project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
        <java.version>1.8</java.version>
    </properties>
    <dependencies>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-data-jpa</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-freemarker</artifactId>
        </dependency>
        <dependency>
            <groupId>com.h2database</groupId>
            <artifactId>h2</artifactId>
            <scope>runtime</scope>
        </dependency>
    </dependencies>
    <build>
        <plugins>
            <plugin>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-maven-plugin</artifactId>
            </plugin>
        </plugins>
    </build>
</project>

3. Project Structure

Refer below screenshot of final project structure for your reference: 

4. JPA Entity - Employee.java

Let's create a JPA entity - Employee class:
package net.guides.springboot2.freemarker.model;

import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.Table;

@Entity
@Table(name = "employees")
public class Employee {

    private long id;
    private String firstName;
    private String lastName;
    private String emailId;

    public Employee() {

    }

    public Employee(String firstName, String lastName, String emailId) {
        this.firstName = firstName;
        this.lastName = lastName;
        this.emailId = emailId;
    }

    @Id
    @GeneratedValue(strategy = GenerationType.AUTO)
    public long getId() {
        return id;
    }
    public void setId(long id) {
        this.id = id;
    }

    @Column(name = "first_name", nullable = false)
    public String getFirstName() {
        return firstName;
    }
    public void setFirstName(String firstName) {
        this.firstName = firstName;
    }

    @Column(name = "last_name", nullable = false)
    public String getLastName() {
        return lastName;
    }
    public void setLastName(String lastName) {
        this.lastName = lastName;
    }

    @Column(name = "email_address", nullable = false)
    public String getEmailId() {
        return emailId;
    }
    public void setEmailId(String emailId) {
        this.emailId = emailId;
    }

    @Override
    public String toString() {
        return "Employee [id=" + id + ", firstName=" + firstName + ", lastName=" + lastName + ", emailId=" + emailId +
            "]";
    }
}

5. JPA Repository - EmployeeRepository.java

package net.guides.springboot2.freemarker.repository;

import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.stereotype.Repository;

import net.guides.springboot2.freemarker.model.Employee;

@Repository
public interface EmployeeRepository extends JpaRepository<Employee, Long>{

}

6. Define Spring Controller - EmployeeController.java

This is the controller class for the Spring Boot web application. A controller is decorated with the @Controller annotation. The controller has two mappings: one mapping for the home page and one for listing all employees.
package net.guides.springboot2.freemarker.controller;

import java.util.HashMap;
import java.util.List;
import java.util.Map;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.servlet.ModelAndView;

import net.guides.springboot2.freemarker.model.Employee;
import net.guides.springboot2.freemarker.repository.EmployeeRepository;

@Controller
public class EmployeeController {
    @Autowired
    private EmployeeRepository employeeRepository;

    @GetMapping("/")
    public String index(Model model) {

        return "index";
    }

    @GetMapping("/showEmployees")
    public ModelAndView showCities() {

        List < Employee > employees = employeeRepository.findAll();

        Map < String, Object > params = new HashMap < String, Object > ();
        params.put("employees", employees);

        return new ModelAndView("showEmployees", params);
    }
}

application.properties

spring.freemarker.template-loader-path: classpath:/templates
spring.freemarker.suffix: .ftl

7. Define View Templates

The index.ftl template file is the home page of the application. It contains a link to retrieve all employees.

index.ftl

<!DOCTYPE html>
<html>
    <head>
        <title>Home page</title>
        <meta charset="UTF-8">
        <meta name="viewport" content="width=device-width, initial-scale=1.0">
        <link href="https://stackpath.bootstrapcdn.com/bootstrap/4.3.1/css/bootstrap.min.css" 
         rel="stylesheet" integrity="sha384-ggOyR0iXCbMQv3Xipma34MD+dH/1fQ784/j6cY/iJTQUOhcWr7x9JvoRxT2MZw1T" 
         crossorigin="anonymous">
    </head>

    <body>
    <div class="container">
      <div class="panel panel-primary">
     <div class="panel-heading">
       <h2>Home Page</h2>
     </div>
         <a href="showEmployees">Show Employees (Retrieve employee data from database)</a>
         </div>
        </div>
    </body>

</html>

showEmployees.ftl

<!DOCTYPE html>
<html>
    <head>
        <title>Employee List</title>
        <meta charset="UTF-8">
        <meta name="viewport" content="width=device-width, initial-scale=1.0">
        <link href="https://stackpath.bootstrapcdn.com/bootstrap/4.3.1/css/bootstrap.min.css" 
         rel="stylesheet" integrity="sha384-ggOyR0iXCbMQv3Xipma34MD+dH/1fQ784/j6cY/iJTQUOhcWr7x9JvoRxT2MZw1T" 
         crossorigin="anonymous">
        <link rel="stylesheet" href="css/style.css">
        </head>
    <body>
    <div class="container">
       <div class="panel panel-primary">
             <div class="panel-heading">
   <h2>Employee List</h2>
             </div>
    <div class="panel-body">            
      <table class="table table-striped">
        <thead>
          <tr>
            <th>Firstname</th>
            <th>Lastname</th>
            <th>Email</th>
          </tr>
        </thead>
        <tbody>
         <#list employees as employee>
                          <tr>
                                <td>${employee.firstName}</td>
                                <td>${employee.lastName}</td>
                                <td>${employee.emailId}</td>
                          </tr>
             </#list>
        </tbody>
      </table>
    </div>
  </div>
           </div>
     </body>
</html>

8. Run Application

We set up the Spring Boot application. The @SpringBootApplication annotation enables auto-configuration and component scanning. We implemented the run() method of CommandLineRunner interface to store a few employee records in the database.
package net.guides.springboot2.freemarker;

import java.util.List;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.CommandLineRunner;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;

import net.guides.springboot2.freemarker.model.Employee;
import net.guides.springboot2.freemarker.repository.EmployeeRepository;

@SpringBootApplication
public class Application implements CommandLineRunner {

    @Autowired
    private EmployeeRepository employeeRepository;

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

    @Override
    public void run(String...args) throws Exception {

        employeeRepository.save(new Employee("Ramesh", "Fadatare", "[email protected]"));
        employeeRepository.save(new Employee("Tom", "Cruise", "[email protected]"));
        employeeRepository.save(new Employee("John", "Cena", "[email protected]"));
        employeeRepository.save(new Employee("tony", "stark", "[email protected]"));
        // get list of employees
        List < Employee > employees = employeeRepository.findAll();
        employees.forEach(employee - > System.out.println(employee.toString()));
    }
}

9. Demo

The application is deployed on the built-in Tomcat server, which listens on port 8080.
Hit http://localhost:8080/ link in a browser will open a home page:
Click on showEmployees will retrieve all employees from the database and populate on this page:
Get source code of this tutorial on my GitHub Repository.

Comments