杰瑞科技汇

Velocity如何调用Java方法?

Velocity 是一个基于 Java 的模板引擎,它允许你使用简单的模板语言来引用由 Java 代码定义的对象,它被广泛用于生成源代码、报告、XML、电子邮件等。

Velocity如何调用Java方法?-图1
(图片来源网络,侵删)

下面我将分步介绍,从环境搭建到核心概念,再到完整的代码示例。


核心概念

在开始之前,理解 Velocity 的三个核心组件非常重要:

  1. 模板: 一个文本文件,通常以 .vm (Velocity Macro) 为后缀,它混合了静态文本和 Velocity 指令(如 #if, #foreach, ),这是你要生成内容的“蓝图”。
  2. 上下文: 一个 Java 对象,通常是 org.apache.velocity.context.Context 的实例(最常用的是它的子类 VelocityContext),它充当 Java 代码和模板之间的“数据桥梁”,你将需要在 Java 程序中生成的数据(如字符串、数字、List、Map 等)作为键值对存入这个上下文。
  3. 引擎: org.apache.velocity.app.VelocityEngine 的实例,它是 Velocity 的核心,负责解析模板、合并上下文数据,并最终生成输出。

整个流程可以概括为:

Java 代码 -> 准备数据 -> 存入 Context -> VelocityEngine 加载模板 -> 合并 Context 和模板 -> 生成 输出 (可以是字符串、文件等)

Velocity如何调用Java方法?-图2
(图片来源网络,侵删)

环境搭建

你需要在你的 Java 项目中添加 Velocity 的依赖。

使用 Maven (推荐)

在你的 pom.xml 文件中添加以下依赖:

<dependencies>
    <!-- Velocity 核心库 -->
    <dependency>
        <groupId>org.apache.velocity</groupId>
        <artifactId>velocity-engine-core</artifactId>
        <version>2.3</version> <!-- 建议使用较新版本 -->
    </dependency>
</dependencies>

使用 Gradle

在你的 build.gradle 文件中添加:

dependencies {
    implementation 'org.apache.velocity:velocity-engine-core:2.3'
}

完整调用示例

下面我们通过一个完整的例子来演示如何从 Java 代码调用 Velocity 模板。

Velocity如何调用Java方法?-图3
(图片来源网络,侵删)

第 1 步:创建模板文件

在你的项目 src/main/resources 目录下创建一个名为 hello.vm 的文件。

src/main/resources/hello.vm

#**
 这是一个 Velocity 模板文件
 *#
## 这是一个注释,不会出现在输出中
## 使用 $ 引用变量
欢迎您, ${name}!
## 使用 #if 进行条件判断
#if ($age >= 18)
您已成年,年龄是 ${age} 岁。
#else
您还未成年,年龄是 ${age} 岁。
#end
## 使用 #foreach 遍历集合
<h3>您的爱好列表:</h3>
<ul>
#foreach ($hobby in $hobbies)
  <li>$hobby</li>
#end
</ul>
## 使用 #set 设置变量
#set ($greeting = "Velocity is fun!")
<p>$greeting</p>

第 2 步:编写 Java 代码

创建一个 Java 类来加载模板、填充数据并生成输出。

HelloVelocity.java

import org.apache.velocity.Template;
import org.apache.velocity.VelocityContext;
import org.apache.velocity.app.VelocityEngine;
import org.apache.velocity.runtime.RuntimeConstants;
import org.apache.velocity.runtime.resource.loader.ClasspathResourceLoader;
import java.io.StringWriter;
import java.util.ArrayList;
import java.util.List;
public class HelloVelocity {
    public static void main(String[] args) {
        // 1. 初始化 VelocityEngine (引擎)
        VelocityEngine velocityEngine = new VelocityEngine();
        // 配置引擎:从 classpath 加载模板文件
        velocityEngine.setProperty(RuntimeConstants.RESOURCE_LOADER, "classpath");
        velocityEngine.setProperty("classpath.resource.loader.class", ClasspathResourceLoader.class.getName());
        // 初始化引擎
        velocityEngine.init();
        // 2. 创建 VelocityContext (上下文) 并填充数据
        VelocityContext context = new VelocityContext();
        context.put("name", "张三");
        context.put("age", 25);
        List<String> hobbies = new ArrayList<>();
        hobbies.add("编程");
        hobbies.add("阅读");
        hobbies.add("旅行");
        context.put("hobbies", hobbies);
        // 3. 加载模板
        Template template = velocityEngine.getTemplate("hello.vm");
        // 4. 合并模板和上下文,生成输出
        StringWriter writer = new StringWriter();
        template.merge(context, writer);
        // 5. 输出结果
        System.out.println("--- Velocity 生成的输出 ---");
        System.out.println(writer.toString());
    }
}

第 3 步:运行和查看结果

运行 HelloVelocitymain 方法,你将在控制台看到以下输出:

--- Velocity 生成的输出 ---
欢迎您, 张三!
您已成年,年龄是 25 岁。
<h3>您的爱好列表:</h3>
<ul>
  <li>编程</li>
  <li>阅读</li>
  <li>旅行</li>
</ul>
<p>Velocity is fun!</p>

关键代码解析

  1. VelocityEngine 初始化与配置:

    • new VelocityEngine(): 创建引擎实例。
    • setProperty(...): 设置引擎属性,这里最关键的是配置资源加载器。
    • RuntimeConstants.RESOURCE_LOADER, "classpath": 指定使用 classpath 资源加载器。
    • "classpath.resource.loader.class", ClasspathResourceLoader.class.getName(): 指定 classpath 加载器的具体实现类,这样 Velocity 就知道去 src/main/resources 等类路径下寻找模板文件。
    • init(): 执行初始化,应用所有配置。
  2. VelocityContext 数据填充:

    • new VelocityContext(): 创建一个空的上下文。
    • context.put("key", value): 向上下文中添加数据,模板中通过 $key 来访问这些数据。value 可以是任何 Java 对象(String, Integer, List, Map, 自定义 POJO 等)。
  3. 加载与合并:

    • velocityEngine.getTemplate("hello.vm"): 根据模板名称从类路径加载模板,如果模板不存在,会抛出异常。
    • new StringWriter(): 创建一个 StringWriter,它就像一个内存中的文本写入器,用于接收模板合并后的结果。
    • template.merge(context, writer): 这是核心步骤,它将上下文中的数据注入模板,并将最终生成的文本写入 StringWriter

进阶用法:将输出写入文件

如果你不想将结果输出到控制台,而是写入到一个文件中,可以使用 FileWriter

import org.apache.velocity.Template;
import org.apache.velocity.VelocityContext;
import org.apache.velocity.app.VelocityEngine;
import org.apache.velocity.runtime.RuntimeConstants;
import org.apache.velocity.runtime.resource.loader.ClasspathResourceLoader;
import java.io.FileWriter;
import java.io.IOException;
import java.io.Writer;
import java.util.Properties;
public class VelocityToFile {
    public static void main(String[] args) {
        // 1. 初始化引擎
        VelocityEngine ve = new VelocityEngine();
        ve.setProperty(RuntimeConstants.RESOURCE_LOADER, "classpath");
        ve.setProperty("classpath.resource.loader.class", ClasspathResourceLoader.class.getName());
        ve.init();
        // 2. 准备上下文数据
        VelocityContext context = new VelocityContext();
        context.put("title", "用户报告");
        context.put("user", new User("李四", 30)); // 也可以传入自定义对象
        // 3. 加载模板
        Template t = ve.getTemplate("report.vm"); // 假设有一个 report.vm 模板
        // 4. 创建文件写入器并合并
        Writer writer = null;
        try {
            // 指定输出文件的路径
            writer = new FileWriter("output/report.html");
            t.merge(context, writer);
            System.out.println("报告已成功生成到 output/report.html");
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            if (writer != null) {
                try {
                    writer.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }
    }
}
// 一个简单的 POJO
class User {
    private String name;
    private int age;
    public User(String name, int age) {
        this.name = name;
        this.age = age;
    }
    // Velocity 会通过反射调用 getter 方法,所以必须有标准的 getter
    public String getName() {
        return name;
    }
    public int getAge() {
        return age;
    }
}

report.vm 示例:

<html>
<head>$title</title>
</head>
<body>
    <h1>用户详情</h1>
    <p>姓名: $user.name</p>
    <p>年龄: $user.age</p>
</body>
</html>

调用 Velocity 的流程非常清晰:

  1. 引入依赖: 在 pom.xmlbuild.gradle 中添加 velocity-engine-core
  2. 准备模板: 在 resources 目录下创建 .vm 文件,使用 Velocity 语法编写内容。
  3. 初始化引擎: 创建 VelocityEngine 实例并配置资源加载器(通常是 ClasspathResourceLoader)。
  4. 填充数据: 创建 VelocityContext,将你的 Java 数据(变量、集合、对象)放入其中。
  5. 加载与合并: 使用引擎加载模板,然后调用 template.merge(context, writer) 生成最终结果。
  6. 处理输出: 将结果输出到控制台、文件、网络响应等任何地方。
分享:
扫描分享到社交APP
上一篇
下一篇