Introduction to Using FreeMarker in Spring MVC

1. Overview

FreeMarker is a Java based template engine from the Apache Software Foundation. Like other template engines, FreeMarker is designed to support HTML web pages in applications following the MVC pattern. This tutorial illustrates how to configure FreeMarker for use in Spring MVC as an alternative to JSP.

The article will not discuss the basics of Spring MVC usage. For an in-depth look at that, please refer to this article. Additionally, this is not intended to be a detailed look at FreeMarker’s extensive capabilities. For more information on FreeMarker usage and syntax, please visit its website.

2. Maven Dependencies

Since this is a Maven-based project, we first add the required dependencies to the pom.xml:

<dependency>
    <groupId>org.freemarker</groupId>
    <artifactId>freemarker</artifactId>
    <version>2.3.23</version>
</dependency>
<dependency>
    <groupId>org.springframework</groupId>
    <artifactId>spring-context-support</artifactId>
    <version>${spring.version}</version>
</dependency>

3. Configurations

Now let’s dive into the configuration of the project. This is an annotation-based Spring project, so we will not demonstrate the XML-based configuration.

3.1. Spring Web Configuration

Let’s create a class to configure web components. For that, we need to annotate the class with @EnableWebMvc@Configuration and @ComponentScan.

@EnableWebMvc
@Configuration
@ComponentScan({"com.maixuanviet.freemarker"})
public class SpringWebConfig extends WebMvcConfigurerAdapter {
    // All web configuration will go here.
}

3.2. Configure ViewResolver

Spring MVC Framework provides the ViewResolver interface, that maps view names to actual views. We will create an instance of FreeMarkerViewResolver, which belongs to spring-webmvc dependency.

That object needs to be configured with the required values that will be used at run-time. For example, we will configure the view resolver to use FreeMarker for views ending in .ftl:

@Bean 
public FreeMarkerViewResolver freemarkerViewResolver() { 
    FreeMarkerViewResolver resolver = new FreeMarkerViewResolver(); 
    resolver.setCache(true); 
    resolver.setPrefix(""); 
    resolver.setSuffix(".ftl"); 
    return resolver; 
}

Also, notice how we can also control the caching mode here – this should only be disabled for debugging and development.

3.3. FreeMarker Template Path Configuration

Next, we will set the template path, which indicates where the templates are located in the web context:

@Bean 
public FreeMarkerConfigurer freemarkerConfig() { 
    FreeMarkerConfigurer freeMarkerConfigurer = new FreeMarkerConfigurer(); 
    freeMarkerConfigurer.setTemplateLoaderPath("/WEB-INF/views/ftl/");
    return freeMarkerConfigurer; 
}

3.4. Spring Controller Configuration

Now we can use a Spring Controller to process a FreeMarker template for display. This is simply a conventional Spring Controller:

@RequestMapping(value = "/cars", method = RequestMethod.GET)
public String init(@ModelAttribute("model") ModelMap model) {
    model.addAttribute("carList", carList);
    return "index";
}

The FreeMarkerViewResolver and path configurations defined previously will take care of translating the view name index to the proper FreeMarker view.

4. FreeMarker HTML Template

4.1. Create Simple HTML Template View

It is now time to create an HTML template with FreeMarker. In our example, we added a list of cars to the model. FreeMarker can access that list and display it by iterating over its contents.

When a request is made for the /cars URI, Spring will process the template using the model that it is provided. In our template, the #list directive indicates that FreeMarker should loop over the carList object from the model, using car to refer to the current element and render the content within that block.

The following code also includes FreeMarker expressions to refer to the attributes of each element in carList; or example, to display the current car element’s make property, we use the expression ${car.make}.

<div id="header">
  <h2>FreeMarker Spring MVC Hello World</h2>
</div>
<div id="content">
  <fieldset>
    <legend>Add Car</legend>
    <form name="car" action="add" method="post">
      Make : <input type="text" name="make" /><br/>
      Model: <input type="text" name="model" /><br/>
      <input type="submit" value="Save" />
    </form>
  </fieldset>
  <br/>
  <table class="datatable">
    <tr>
      <th>Make</th>
      <th>Model</th>
    </tr>
    <#list model["carList"] as car>
      <tr>
        <td>${car.make}</td>
        <td>${car.model}</td>
      </tr>
    </#list>
  </table>
</div>

After styling the output with CSS, the processed FreeMarker template generates a form and list of cars:

browser_localhost-300x235

5. Spring Boot

If we’re using Spring Boot, we can simply import the spring-boot-starter-freemarker dependency:

<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-freemarker</artifactId>
    <version>2.3.4.RELEASE</version>
</dependency>

Then, we simply have to add our template files under src/main/resources/templates. Spring Boot is in charge of other default configurations like FreeMarkerConfigurer and FreeMarkerViewResolver.

6. Conclusion

In this article, we discussed how to integrate FreeMarker in a Spring MVC application. FreeMarker’s capabilities go far beyond what we demonstrated, so please visit the Apache FreeMarker website for more detailed information on its use.

The sample code in this article is available in a project on Github.

Related posts:

Spring Boot Annotations
Remove All Occurrences of a Specific Value from a List
Hướng dẫn Java Design Pattern – MVC
Chương trình Java đầu tiên
Guide to the Java TransferQueue
How to Get All Spring-Managed Beans?
Từ khóa static và final trong java
How to Round a Number to N Decimal Places in Java
Upload and Display Excel Files with Spring MVC
Lớp Collections trong Java (Collections Utility Class)
Posting with HttpClient
Using the Not Operator in If Conditions in Java
Using a Mutex Object in Java
The Order of Tests in JUnit
How to Get a Name of a Method Being Executed?
Java Program to Find Nearest Neighbor Using Linear Search
Cài đặt và sử dụng Swagger UI
Concatenating Strings In Java
Constructor Injection in Spring with Lombok
Hướng dẫn Java Design Pattern – Chain of Responsibility
“Stream has already been operated upon or closed” Exception in Java
Abstract class và Interface trong Java
Java Program to Generate a Sequence of N Characters for a Given Specific Case
Derived Query Methods in Spring Data JPA Repositories
Java Program to find the peak element of an array using Binary Search approach
Spring Cloud AWS – Messaging Support
Java Program to Check if any Graph is Possible to be Constructed for a Given Degree Sequence
OAuth2 for a Spring REST API – Handle the Refresh Token in Angular
Java Program to Implement Direct Addressing Tables
Java Program to Implement Sorted Vector
Lập trình đa luồng với CompletableFuture trong Java 8
REST Web service: Upload và Download file với Jersey 2.x