Spring 5's reactive module supports FreeMarker components to provide templates to reactive contents. Let us implement FreeMarker templating using the Spring Reactive module:
- Add the newest Maven dependencies of FreeMarker in pom.xml:
<dependency> <groupId>org.freemarker</groupId> <artifactId>freemarker</artifactId> <version>2.3.26-incubating</version> </dependency>
- To add the reactive components to the application, include the following Maven dependency that implements the Reactor Core implementation of the Reactive Streams specification:
<dependency> <groupId>org.springframework</groupId> <artifactId>spring-web-reactive</artifactId> <version>${spring.version}</version> </dependency>
- To avoid conflicts with other non-reactive web configurations, create a root context definition SpringWebReactiveConfig that implements org.springframework.web.reactive.config.WebReactiveConfigurer. This definition will inject all reactive view engines and resolvers needed to render Publisher<T> streams:
@EnableWebMvc @ComponentScan(basePackages="org.packt.web.reactor") @PropertySource("classpath:config/jdbc.properties") @Configuration public class SpringWebReactiveConfig implements WebReactiveConfigurer { }
- Inject the following FreeMarker bean configuration in the SpringWebReactiveConfig context definition. Set the FreeMarker template location in WEB-INF emplates:
@Bean(name = "viewResolverFTL") public FreeMarkerViewResolver getViewResolverFtl() { FreeMarkerViewResolver viewResolver = new FreeMarkerViewResolver(); viewResolver.setPrefix(""); viewResolver.setSuffix(".ftl"); viewResolver.setOrder(1); return viewResolver; } @Bean(name = "freemarkerConfig") public FreeMarkerConfigurer getFreemarkerConfig() { FreeMarkerConfigurer config = new FreeMarkerConfigurer(); config.setTemplateLoaderPath("/WEB-INF/templates/"); return config; }
- Create a RenderController that will publish a list of employees in an FTL template.
@Controller public class RenderController { @Autowired private EmployeeService employeeServiceImpl; @RequestMapping(value="/ftl/empList.html", method=RequestMethod.GET) public String usersFtl(Model model){ model.addAttribute("employees", employeeServiceImpl.readEmployeesByDescAge() .collectList().block()); return "ftl_list_emps"; } }
- Inside the path WEB-INF emplates, create an FTL template ftl_list_emps.ftl that will serve as the physical view:
<!DOCTYPE html> <html> <head> <title>Ch08 FreeMarker Reactive View</title> </head> <body> <table> <thead> <tr> <th>Employee ID</th> <th>First Name</th> <th>Last Name</th> <th>Age</th> </tr> </thead> <tbody> <#list employees as e> <tr> <td>${e.empId?html}</td> <td>${e.firstName?html}</td> <td>${e.lastName?html}</td> <td>${e.age?html}</td> </tr> </#list> </tbody> </table> </body> </html>
- Save all files. Then, clean, build, and deploy. Run the URL on the browser and expect the following result: