The Master Class of "Learn Spring Security" is out:
1. Introduction
Velocity is a template engine from the Apache Software Foundation that can work with normal text files, SQL, XML, Java code and many other types.
In this article we’re going to focus on utilizing Velocity with a typical Spring MVC web application.
2. Maven Dependencies
Let’s start by enabling the Velocity support – with the following dependencies:
<dependency> <groupId>org.apache.velocity</groupId> <artifactId>velocity</artifactId> <version>1.7</version> </dependency> <dependency> <groupId>org.apache.velocity</groupId> <artifactId>velocity-tools</artifactId> <version>2.0</version> </dependency>
The newest versions of both can be found here: velocity and velocity-tools.
3. Configuration
3.1. Web Config
If we don’t want to use an web.xml, let’s configure our web project using Java and an initializer:
public class MainWebAppInitializer implements WebApplicationInitializer { @Override public void onStartup(ServletContext sc) throws ServletException { AnnotationConfigWebApplicationContext root = new AnnotationConfigWebApplicationContext(); root.register(WebConfig.class); sc.addListener(new ContextLoaderListener(root)); ServletRegistration.Dynamic appServlet = sc.addServlet("mvc", new DispatcherServlet(new GenericWebApplicationContext())); appServlet.setLoadOnStartup(1); } }
Alternatively, we can of course use the traditional web.xml:
<web-app ...> <display-name>Spring MVC Velocity</display-name> <servlet> <servlet-name>mvc</servlet-name> <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class> <init-param> <param-name>contextConfigLocation</param-name> <param-value>/WEB-INF/mvc-servlet.xml</param-value> </init-param> <load-on-startup>1</load-on-startup> </servlet> <servlet-mapping> <servlet-name>mvc</servlet-name> <url-pattern>/*</url-pattern> </servlet-mapping> <context-param> <param-name>contextConfigLocation</param-name> <param-value>/WEB-INF/spring-context.xml</param-value> </context-param> <listener> <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class> </listener> </web-app>
Notice that we mapped our servlet on the “/*” path.
3.2. Spring Config
Let’s now go over a simple Spring configuration – again, starting with Java:
@Configuration @EnableWebMvc @ComponentScan(basePackages= { "com.baeldung.mvc.velocity.controller", "com.baeldung.mvc.velocity.service" }) public class WebConfig extends WebMvcConfigurerAdapter { @Override public void addResourceHandlers(ResourceHandlerRegistry registry) { registry .addResourceHandler("/resources/**") .addResourceLocations("/resources/"); } @Override public void configureDefaultServletHandling(DefaultServletHandlerConfigurer configurer) { configurer.enable(); } @Bean public ViewResolver viewResolver() { VelocityLayoutViewResolver bean = new VelocityLayoutViewResolver(); bean.setCache(true); bean.setPrefix("/WEB-INF/views/"); bean.setLayoutUrl("/WEB-INF/layouts/layout.vm"); bean.setSuffix(".vm"); return bean; } @Bean public VelocityConfigurer velocityConfig() { VelocityConfigurer velocityConfigurer = new VelocityConfigurer(); velocityConfigurer.setResourceLoaderPath("/"); return velocityConfigurer; } }
And let’s also have a quick look at the XML version of the configuration:
<beans ...> <context:component-scan base-package="com.baeldung.mvc.velocity.*" /> <context:annotation-config /> <bean id="velocityConfig" class="org.springframework.web.servlet.view.velocity.VelocityConfigurer"> <property name="resourceLoaderPath"> <value>/</value> </property> </bean> <bean id="viewResolver" class="org.springframework.web.servlet.view.velocity.VelocityLayoutViewResolver"> <property name="cache" value="true" /> <property name="prefix" value="/WEB-INF/views/" /> <property name="layoutUrl" value="/WEB-INF/layouts/layout.vm" /> <property name="suffix" value=".vm" /> </bean> </beans>
Here we are telling Spring where to look for annotated bean definitions:
<context:component-scan base-package="com.baeldung.mvc.velocity.*" />
We are indicating we are going to use annotation-driven configuration in our project with the following line:
<context:annotation-config />
By creating “velocityConfig” and “viewResolver” beans we are telling VelocityConfigurer where to look for templates, and VelocityLayoutViewResolver where to find views and layouts.
4. Velocity Templates
Finally, let’s create our templates – starting with a common header:
<div style="..."> <div style="float: left"> <h1>Our tutorials</h1> </div> </div>
and footer:
<div style="..."> @Copyright baeldung.com </div>
And let’s define a common layout for our site where we are going to use above fragments with parse in the following code:
<html> <head> <title>Spring & Velocity</title> </head> <body> <div> #parse("/WEB-INF/fragments/header.vm") </div> <div> <!-- View index.vm is inserted here --> $screen_content </div> <div> #parse("/WEB-INF/fragments/footer.vm") </div> </body> </html>
You can check that $screen_content variable has the content of the pages.
Finally, we’ll create a template for the main content:
<h1>Index</h1> <h2>Tutorials list</h2> <table border="1"> <tr> <th>Tutorial Id</th> <th>Tutorial Title</th> <th>Tutorial Description</th> <th>Tutorial Author</th> </tr> #foreach($tut in $tutorials) <tr> <td>$tut.tutId</td> <td>$tut.title</td> <td>$tut.description</td> <td>$tut.author</td> </tr> #end </table>
5. Controller Side
We have created a simple controller which returns a list of tutorials as content for our layout to be populated with:
@Controller @RequestMapping("/") public class MainController { @Autowired private ITutorialsService tutService; @RequestMapping(value ="/", method = RequestMethod.GET) public String defaultPage() { return "index"; } @RequestMapping(value ="/list", method = RequestMethod.GET) public String listTutorialsPage(Model model) { List<Tutorial> list = tutService.listTutorials(); model.addAttribute("tutorials", list); return "index"; } }
Finally, we can access this simple example locally – for example at: localhost:8080/spring-mvc-velocity/
6. Conclusion
In this simple tutorial, we have configured Spring MVC web application with Velocity template engine.
The full sample code for this tutorial can be found in our GitHub repository.