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的效果是一样的。

作者:Gacfox
版权声明:本网站为非盈利性质,文章如非特殊说明均为原创,版权遵循知识共享协议CC BY-NC-ND 4.0进行授权,转载必须署名,禁止用于商业目的或演绎修改后转载。