Quick Guide to Spring MVC with Velocity

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.maixuanviet.mvc.velocity.controller",
  "com.maixuanviet.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.maixuanviet.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.maixuanviet.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 maixuanviet.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.

Related posts:

Java Program to Implement Cubic convergence 1/pi Algorithm
Java Program to Find Hamiltonian Cycle in an UnWeighted Graph
The DAO with Spring and Hibernate
Java – InputStream to Reader
Convert String to int or Integer in Java
Object Type Casting in Java
A Guide to Apache Commons Collections CollectionUtils
Java Program to Implement PriorityQueue API
Java Program to Find Transitive Closure of a Graph
Using Spring @ResponseStatus to Set HTTP Status Code
Java Program to Implement Merge Sort on n Numbers Without tail-recursion
Using JWT with Spring Security OAuth
How to Count Duplicate Elements in Arraylist
Java Program to Implement Bubble Sort
Java Program to Generate All Possible Subsets with Exactly k Elements in Each Subset
Jackson – Unmarshall to Collection/Array
HandlerAdapters in Spring MVC
Tìm hiểu về xác thực và phân quyền trong ứng dụng
RegEx for matching Date Pattern in Java
Tính kế thừa (Inheritance) trong java
Sao chép các phần tử của một mảng sang mảng khác như thế nào?
Disable Spring Data Auto Configuration
Java Program to Check if a Given Set of Three Points Lie on a Single Line or Not
Calling Stored Procedures from Spring Data JPA Repositories
Debug a HttpURLConnection problem
Java Program to Implement Tarjan Algorithm
Refactoring Design Pattern với tính năng mới trong Java 8
Java Program to Test Using DFS Whether a Directed Graph is Weakly Connected or Not
Spring Data JPA and Null Parameters
Java Program to Implement Graph Structured Stack
Simultaneous Spring WebClient Calls
Biến trong java