This example demonstrates how to use Apache FreeMarker templates as the view technology in a Spring MVC application.
Example
Maven dependencies
pom.xml<dependency>
<groupId>org.freemarker</groupId>
<artifactId>freemarker</artifactId>
<version>2.3.35</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context-support</artifactId>
<version>7.0.6</version>
</dependency>
spring-context-support contains Spring's base FreeMarker support classes (for example, FreeMarkerConfigurationFactory, which FreeMarkerConfigurer extends). The same module also provides integration with other common third-party libraries, such as Quartz, Jakarta Mail and caching providers.
Java Config class
package com.logicbig.example;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.servlet.ViewResolver;
import org.springframework.web.servlet.config.annotation.EnableWebMvc;
import org.springframework.web.servlet.config.annotation.ViewResolverRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;
import org.springframework.web.servlet.config.annotation.ViewResolverRegistry;
import org.springframework.web.servlet.view.freemarker.FreeMarkerConfigurer;
import org.springframework.web.servlet.view.freemarker.FreeMarkerViewResolver;
@EnableWebMvc
@Configuration
@ComponentScan
public class MyWebConfig implements WebMvcConfigurer {
@Override
public void configureViewResolvers (ViewResolverRegistry registry) {
registry.freeMarker();
}
@Bean
public FreeMarkerConfigurer freeMarkerConfigurer() {
FreeMarkerConfigurer configurer =
new FreeMarkerConfigurer();
configurer.setTemplateLoaderPath("/WEB-INF/views/");
return configurer;
}
}
Writing a Spring Controller
package com.logicbig.example;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.RequestMapping;
import java.time.LocalTime;
@Controller
@RequestMapping("/")
public class MyController {
@RequestMapping
public String handleRequest(Model model) {
model.addAttribute("msg",
"A message from the controller");
model.addAttribute("time", LocalTime.now());
return "my-page";
}
}
The FreeMarker template
src/main/webapp/WEB-INF/views/my-page.ftl<!DOCTYPE html>
<html lang="en">
<body>
<h2>FreeMarker View</h2>
<div> Message: ${msg}</div>
<div> Time: ${time} </div>
</body>
</html>
This diagram shows how freemarker works with Spring:
More information about the FreeMarker template engine can be found here.
Running the example
To try examples, run embedded Jetty (configured in pom.xml of example project below):
mvn jetty:run
Output
 $ curl -s "http://localhost:8080" <!DOCTYPE html> <html lang="en"> <body> <h2>FreeMarker View</h2> <div> Message: A message from the controller</div> <div> Time: 05:40:01.494 </div> </body> </html>
Example ProjectDependencies and Technologies Used: - spring-webmvc 7.0.6 (Spring Web MVC)
Version Compatibility: 4.1.0.RELEASE - 7.0.6 Version compatibilities of spring-webmvc with this example: Versions in green have been tested.
- spring-context-support 7.0.6 (Spring Context Support)
- freemarker 2.3.35 (FreeMarker is a "template engine"; a generic tool to generate text output based on templates)
- jakarta.servlet-api 6.1.0 (Jakarta Servlet API documentation)
- JDK 25
- Maven 3.9.11
|