HelloKoding

Practical coding guides

Spring Boot FreeMarker Tutorial with Example

This tutorial walks you through the steps of creating a Hello World web app example with Spring Boot and FreeMarker

What you’ll build

Spring Boot Hello World

What you’ll need

  • Your favorite IDE
  • JDK 8+ or OpenJDK 8+
  • Maven 3+

The tech stack

  • Spring Boot is a popular Java based framework used to build production-grade web applications and services
  • FreeMarker is a Java based server-side template engine

Init project structure

You can create and init a new Spring Boot project by using Spring CLI or Spring Initializr. Learn more about using these tools at here

The final project structure as below

├── src
│   └── main
│       ├── java
│       │   └── com
│       │       └── hellokoding
│       │           └── springboot
│       │               └── view
│       │                   ├── Application.java
│       │                   └── HelloController.java
│       └── resources
│           ├── static
│           │   ├── css
│           │   │   └── main.css
│           │   └── js
│           │       └── main.js
│           ├── templates
│           │   └── hello.ftl
│           └── application.properties
└── pom.xml

Project dependencies

Add spring-boot-starter-web and spring-boot-starter-freemarker into your project as a dependency on pom.xml or build.gradle file. The library versions can be omitted as it is resolved by the parent pom provided by Spring Boot

<dependencies>
    <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>
</dependencies>

You can find the full pom.xml file as below

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.hellokoding.springboot</groupId>
    <artifactId>freemarker-helloworld</artifactId>
    <version>1.0-SNAPSHOT</version>

    <parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>2.2.2.RELEASE</version>
    </parent>

    <properties>
        <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
        <java.version>1.8</java.version>
    </properties>

    <dependencies>
        <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>
    </dependencies>

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

Define Controller

HelloController.java

package com.hellokoding.springboot.view;

import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestParam;

@Controller
public class HelloController {
    @GetMapping({"/", "/hello"})
    public String hello(Model model,
                        @RequestParam(value="name", required=false, defaultValue="World") String name) {
        model.addAttribute("name", name);
        return "hello";
    }
}

@Controller indicates the annotated class is a web controller

@GetMapping maps HTTP GET request for ”/” (home page) and “/hello” to the hello method

@RequestParam binds method parameter name to request query string parameter (value="name",...)

Model is an object sharing data between handler and view template

The view template name is defined by the return statement of the handler and the spring.freemarker.suffix config property which defined in the below application.properties file. So in this hello handler method, the return view is hello.ftl

View Template

hello.ftl

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Hello ${name}!</title>
    <link href="/css/main.css" rel="stylesheet">
</head>
<body>
    <h2 class="hello-title">Hello ${name}!</h2>
    <script src="/js/main.js"></script>
</body>
</html>

Static files

main.css

.hello-title{
    color: darkgreen;
}

main.js

(function(){
    console.log("Hello World!");
})();

Application Configurations

Application.java

package com.hellokoding.springboot.view;

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.properties

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

Run and Test

You can run the application by typing the following command on terminal console at the project root directory

$ mvn clean spring-boot:run

You would see this text in the console

o.s.b.w.embedded.tomcat.TomcatWebServer  : Tomcat started on port(s): 8080 (http) with context path ''

Access to http://localhost:8080 on your web browser, the following response is expected

Hello, World!

Source code

https://github.com/hellokoding/hellokoding-courses/tree/master/springboot-examples/springboot-freemarker-helloworld

Follow HelloKoding