Velocity简介
Apache Velocity一个基于Java语言开发的模板引擎,通过Velocity特定的语法VTL,我们能够在一段文本(模板)中引用Java对象的属性,以达到基于模板和数据模型生成特定文本的目的。
将模板引擎用于Web开发则能够实现将Java代码从显示的页面中分离的目的,便于界面设计人员和Java程序员的分工。和JSP相比,Velocity用途更加广泛,在许多需要模板的地方都可以使用Velocity,例如发送邮件等。而在Web开发中,Velocity有更简洁易用的语法,它也很适合与美工人员协同开发,遇到较复杂的网页布局这种优势就会更加明显。
官方文档:http://velocity.apache.org/可以下载velocity
引入Maven依赖
使用Velocity模板引擎需要在pom.xml中引入以下Maven依赖。
<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>
Hello World
这里我们先写一个最简单的例子,例子中读取一个Velocity模板文件hello.vm然后输出通过模板生成的内容。
Demo.java
package com.gacfox.demo;
import org.apache.velocity.Template;
import org.apache.velocity.VelocityContext;
import org.apache.velocity.app.VelocityEngine;
import java.io.StringWriter;
public class Demo {
public static void main(String[] args) throws Exception {
VelocityEngine ve = new VelocityEngine();
Template template = ve.getTemplate("helloVM/hello.vm");
VelocityContext velocityContext = new VelocityContext();
velocityContext.put("txt", "hello, world!");
StringWriter stringWriter = new StringWriter();
template.merge(velocityContext, stringWriter);
System.out.println(stringWriter.toString());
}
}
代码中首先初始化一个Velocity引擎并载入一个.vm文件,.vm就是Velocity模板文件的标准后缀。随后我们初始化Velocity上下文,并将一个叫做hello, world!的字符串以一个名为txt的键加入Velocity上下文中,然后输出最终结果。
hello.vm的内容非常简单,其内容为$txt。
代码输出结果如下图所示。

可以看到,hello,world!字符串通过键值替换了vm中的$txt,最终输出结果为hello,world!。
Servlet环境下使用Velocity
下面我们介绍Velocity在Web开发中的应用,我们这里搭建一个JavaWeb工程,然后使用Velocity作为视图模板进行网页内容的展示。
web.xml
<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns="http://java.sun.com/xml/ns/javaee"
xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd"
id="WebApp_ID" version="3.0">
<display-name>Demo VM</display-name>
<servlet>
<servlet-name>velocity</servlet-name>
<servlet-class>org.apache.velocity.tools.view.VelocityViewServlet</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>velocity</servlet-name>
<url-pattern>*.vm</url-pattern>
</servlet-mapping>
</web-app>
在web.xml中我们配置了VelocityViewServlet,这是一个由velocity-tools包提供的类,它用于拦截了所有对于.vm文件的请求。我们可以打开该Servlet的源码观看,其实现的功能实际上就是拦截对Velocity模板的请求然后读取相应模板,并调用Velocity模板引擎进行输出,因此我们大可不必自己实现一个同样的Servlet,用第一节hello world的方式操作Velocity模板引擎和Velocity上下文。
这里我们编写一个简单的Servlet进行简单的验证。
package com.gacfox.web.controller;
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
@WebServlet(name = "TestServlet", urlPatterns = "/testVelocity")
public class TestServlet extends HttpServlet {
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
doGet(request, response);
}
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
request.setAttribute("txt", "hello velocity from servlet!");
request.getRequestDispatcher("/WEB-INF/views/test.vm").forward(request, response);
}
}
代码中,我们向Request域中放入了一个叫做txt的属性,然后指定了Velocity视图的路径,这和使用JSP视图做法是一样的。在/WEB-INF/views文件夹下我们创建test.vm模板文件,其内容如下。
<!DOCTYPE html>
<html lang="zh">
<head>
<meta charset="UTF-8">
<title>Test Velocity</title>
</head>
<body>
<p>$txt</p>
</body>
</html>
和之前第一节hello world中做法一样,这里我们还是使用$txt输出内容,有所不同的是这里还添加了标准的HTML格式。
启动服务器访问Servlet,可以观察到输出结果。

我们可以观察浏览器中得到的网页源代码。
<!DOCTYPE html>
<html lang="zh">
<head>
<meta charset="UTF-8">
<title>Test Velocity</title>
</head>
<body>
<p>hello velocity from servlet!</p>
</body>
</html>
通过查看网页源代码,可以看到输出的全部HTML代码,$txt被我们指定的字符串hello velocity from servlet!替代。
除了Request域,我们还经常使用Session输出登录用户,因此还可以试验下在其他域中添加属性是否能够正常输出,我们可以在Servlet中添加以下内容。
this.getServletContext().setAttribute("context", "This is context");
request.getSession().setAttribute("session", "This is session");
request.setAttribute("request", "This is request");
request.getRequestDispatcher("/WEB-INF/views/test.vm").forward(request, response);
在test.vm中加入$context、$session、$request,输出结果如下图所示。

可以看到和JSP的效果是一样的。