Apache Velocity Web Application Example Tutorial

In this tutorial, we will learn how to use Apache Velocity to build web applications. In order to use Velocity in a web application, we will need a servlet or servlet-based framework. The easiest way to get started is with VelocityViewServlet in the Velocity Tools subproject.

Tools and technologies used

  • Servlet - 2+
  • Apache Velocity - 1.7
  • Maven - 3+
  • JDK - 1.8+
  • Eclipse IDE
  • Apache Tomcat - 8.5

Development Steps

  1. Create a Maven Web Project
  2. Add Maven Dependencies
  3. Project Structure
  4. Create User and UserService Classes
  5. Create UserServlet
  6. Create LayoutServlet
  7. Web Configuration
  8. Resource Loader
  9. Velocity Templates
  10. Managing the Page Layout
  11. Demo

1. Create a Maven Web Project

Use below article to create a maven web project in Eclipse IDE.

2. Add Maven Dependencies

To work with Velocity, we need to add the following dependencies to our Maven project:
<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>
Here is the complete pom.xml file:
<project
    xmlns="http://maven.apache.org/POM/4.0.0"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
 xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
    <modelVersion>4.0.0</modelVersion>
    <groupId>net.javaguides</groupId>
    <version>0.1-SNAPSHOT</version>
    <artifactId>apache-velocity</artifactId>
    <name>apache-velocity</name>
    <packaging>war</packaging>
    <dependencies>
        <dependency>
            <groupId>org.apache.velocity</groupId>
            <artifactId>velocity</artifactId>
            <version>${velocity-version}</version>
        </dependency>
        <dependency>
            <groupId>org.apache.velocity</groupId>
            <artifactId>velocity-tools</artifactId>
            <version>${velocity-tools-version}</version>
        </dependency>
        <dependency>
            <groupId>org.apache.httpcomponents</groupId>
            <artifactId>httpclient</artifactId>
            <version>${org.apache.httpcomponents.version}</version>
            <scope>test</scope>
            <exclusions>
                <exclusion>
                    <artifactId>commons-logging</artifactId>
                    <groupId>commons-logging</groupId>
                </exclusion>
            </exclusions>
        </dependency>
    </dependencies>
    <build>
        <finalName>apache-velocity</finalName>
        <resources>
            <resource>
                <directory>src/main/resources</directory>
                <filtering>true</filtering>
            </resource>
        </resources>
        <plugins>
            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-war-plugin</artifactId>
                <version>3.2.2</version>
                <configuration>
                    <failOnMissingWebXml>false</failOnMissingWebXml>
                </configuration>
            </plugin>
            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-compiler-plugin</artifactId>
                <version>3.8.1</version>
                <configuration>
                    <source>1.8</source>
                    <target>1.8</target>
                </configuration>
            </plugin>
        </plugins>
    </build>
    <properties>
        <org.apache.httpcomponents.version>4.5.2</org.apache.httpcomponents.version>
        <velocity-version>1.7</velocity-version>
        <velocity-tools-version>2.0</velocity-tools-version>
    </properties>
</project>

3. Project Structure

Use below screenshot to create project structure or packing structure -

4. Create User and UserService Classes

Let's create User POJO class with following content:
package net.javaguides.apache.velocity.model;

public class User {

    private String firstName;
    private String lastName;

    public User(String firstName, String lastName) {
        super();
        this.firstName = firstName;
        this.lastName = lastName;
    }

    public String getFirstName() {
        return firstName;
    }
    public String getLastName() {
        return lastName;
    }
    public void setFirstName(String firstName) {
        this.firstName = firstName;
    }
    public void setLastName(String lastName) {
        this.lastName = lastName;
    }
}
Let's create UserService class which creates and returns list of users to Servlet. 
Here is the complete code:
package net.javaguides.apache.velocity.service;

import java.util.Arrays;
import java.util.List;

import net.javaguides.apache.velocity.model.User;

public class UserService {

    public List < User > getUsers() {
        System.out.println("User service returning list of Users");

        return Arrays.asList(new User("Ramesh", "Fadatare"),
            new User("Tony", "Stark"),
            new User("Tom", "Cruise"));
    }
}

5. Velocity Servlet - Create UserServlet

Velocity provides one out of the box implementation VelocityViewServlet, which is a part of the velocity-tools subproject.
To make use of the built-in functionality provided by VelocityViewServlet, we can extend our servlet from VelocityViewServlet and override the handleRequest() method:
package net.javaguides.apache.velocity.servlet;

import java.util.List;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.apache.velocity.Template;
import org.apache.velocity.context.Context;
import org.apache.velocity.tools.view.VelocityViewServlet;

import net.javaguides.apache.velocity.model.User;
import net.javaguides.apache.velocity.service.UserService;

public class UserServlet extends VelocityViewServlet {

    private static final long serialVersionUID = 1 L;

    UserService service = new UserService();

    @Override
    public Template handleRequest(HttpServletRequest request, HttpServletResponse response, Context context) {

        List < User > users = service.getUsers();

        context.put("users", users);

        Template template = null;

        try {
            template = getTemplate("templates/index.vm");
            response.setHeader("Template Returned", "Success");
        } catch (Exception e) {
            e.printStackTrace();
        }

        return template;
    }
}

6. Velocity Servlet - Create LayoutServlet

Let's create LayoutServlet which extends VelocityViewServlet:
package net.javaguides.apache.velocity.servlet;

import java.util.List;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.apache.velocity.Template;
import org.apache.velocity.context.Context;
import org.apache.velocity.tools.view.VelocityLayoutServlet;

import net.javaguides.apache.velocity.model.User;
import net.javaguides.apache.velocity.service.UserService;

public class LayoutServlet extends VelocityLayoutServlet {
    private static final long serialVersionUID = 1 L;
    UserService service = new UserService();

    @Override
    public Template handleRequest(HttpServletRequest request, HttpServletResponse response, Context context) {

        List < User > users = service.getUsers();

        context.put("users", users);

        Template template = null;

        try {
            template = getTemplate("templates/layoutdemo.vm");

            response.setHeader("Template Returned", "Success");
        } catch (Exception e) {
            e.printStackTrace();
        }
        return template;
    }
}

7. Web Configuration

Let's see how to configure all the Servlets in web.xml file. The servlet is defined for intercepting the requests for velocity template pages and the layout specific properties are defined in velocity.properties file. The velocity.properties file defined in the next step.
Here is the complete web.xml with all the servlet configured:
<!DOCTYPE web-app PUBLIC
 "-//Sun Microsystems, Inc.//DTD Web Application 2.3//EN"
 "http://java.sun.com/dtd/web-app_2_3.dtd" >
<web-app>
    <display-name>apache-velocity</display-name>
    <servlet>
        <servlet-name>UserServlet</servlet-name>
        <servlet-class>net.javaguides.apache.velocity.servlet.UserServlet</servlet-class>
    </servlet>
    <servlet>
        <servlet-name>LayoutServlet</servlet-name>
        <servlet-class>net.javaguides.apache.velocity.servlet.LayoutServlet</servlet-class>
    </servlet>
    <servlet>
        <servlet-name>velocityLayout</servlet-name>
        <servlet-class>org.apache.velocity.tools.view.VelocityLayoutServlet</servlet-class>
        <init-param>
            <param-name>org.apache.velocity.properties</param-name>
            <param-value>/WEB-INF/velocity.properties</param-value>
        </init-param>
    </servlet>
    <servlet-mapping>
        <servlet-name>UserServlet</servlet-name>
        <url-pattern>/</url-pattern>
    </servlet-mapping>
    <servlet-mapping>
        <servlet-name>LayoutServlet</servlet-name>
        <url-pattern>/layout</url-pattern>
    </servlet-mapping>
    <servlet-mapping>
        <servlet-name>velocityLayout</servlet-name>
        <url-pattern>*.vm</url-pattern>
    </servlet-mapping>
    <!-- session timeout -->
    <session-config>
        <session-timeout>
   30
  </session-timeout>
    </session-config>
    <!-- welcome file -->
    <welcome-file-list>
        <welcome-file>index.html</welcome-file>
    </welcome-file-list>
</web-app>
We also need to specify the mapping for this servlet. All the requests for velocity templates (*.vm) need to be served by the velocity servlet:
<servlet-mapping>
    <servlet-name>velocityLayout</servlet-name>
    <url-pattern>*.vm</url-pattern>
</servlet-mapping>

8. Resource Loader

Velocity provides a flexible resource loader system. It allows one or more resource loader to be in operation at the same time:
  • FileResourceLoader
  • JarResourceLoader
  • ClassPathResourceLoader
  • URLResourceLoader
  • DataSourceResourceLoader
  • WebappResourceLoader
These resource loaders are configured in velocity.properties:
resource.loader=webapp
webapp.resource.loader.class=org.apache.velocity.tools.view.WebappResourceLoader
webapp.resource.loader.path = 
webapp.resource.loader.cache = true

9. Velocity Templates

Let's define the velocity index.vm template:

index.vm

<HTML>
<HEAD>
    <TITLE>Online Electronic Store</TITLE>
    <style>
        body {background-color: powderblue;}
        h1   {color: blue;}
        p    {color: red;}
        table.gridtable {
            font-family: verdana,arial,sans-serif;
            font-size:11px;
            color:#333333;
            border-width: 1px;
            border-color: #666666;
            border-collapse: collapse;
        }
        table.gridtable th {
            border-width: 1px;
            padding: 8px;
            border-style: solid;
            border-color: #666666;
            background-color: tomato;
        }
        table.gridtable td {
            border-width: 1px;
            padding: 8px;
            border-style: solid;
            border-color: #666666;
            background-color: tomato;
        }

    </style>

</HEAD>
<BODY>
<CENTER>
    <h2>Users</h2>
    <BR/>
    #set( $count = 1 )
    <TABLE class="gridtable">
        <TR>
            <TH>Serial #</TH><TH>First Name</TH><TH>Last Name</TH>
        </TR>
        #foreach( $user in $users )
            <TR>
                <TD>$count)</TD>
                <TD>$user.getFirstName()</TD>
                <TD>$user.getLastName()</TD>
            </TR>
            #set( $count = $count + 1 )
        #end
    </TABLE>
    <BR/>
</CENTER>

</BODY>
</HTML>

10. Managing the Page Layout

Velocity provides a simple layout control and customizable error screens for Velocity Tool based applications.
VelocityLayoutServlet encapsulates this capability to render the specified layouts. VelocityLayoutServlet is an extension to VelocityViewServlet.

Layout Templates

The layout template defines the typical structure of a velocity page. By default, the VelocityLayoutServlet searches for Default.vm under the layout folder. Overriding a few properties can change this location:
tools.view.servlet.layout.directory = layout/
tools.view.servlet.layout.default.template = Default.vm

Default.vm

The layout file consists of the header template, footer template, and a velocity variable $screen_content which renders the contents of the requested velocity page.
<html>
<head>
 <title>Velocity</title>
</head>
<body>
  <div>
      #parse("/fragments/header.vm")
  </div>
  
  
  <div>
  
    <!-- View index.vm is inserted here -->
    $screen_content
 
  </div>
  
  <div>
      #parse("/fragments/footer.vm")
  </div>
</body>
</html>

header.vm

<div style="background: tomato; height: 80px; padding: 5px;">
  <div style="float: left">
      <h1> Layout Demo Page</h1>
  </div>
</div> 

footer.vm

<div
   style="background: tomato; text-align: center; padding: 5px; margin-top: 10px;">
   @Copyright javaguides.net
</div>

layoutdemo.vm

#set( $layout = "layout.vm" )
<CENTER>
     <h2>Users</h2>
    <BR/>
    #set( $count = 1 )
    <TABLE class="gridtable">
        <TR>
            <TH>Serial #</TH><TH>First Name</TH><TH>Last Name</TH>
        </TR>
        #foreach( $user in $users )
            <TR>
                <TD>$count)</TD>
                <TD>$user.getFirstName()</TD>
                <TD>$user.getLastName()</TD>
            </TR>
            #set( $count = $count + 1 )
        #end
    </TABLE>
    <BR/>
</CENTER>

11. Demo

Users Page:

Layout Page:



Comments