由于项目需要用到了velocity,真是感觉相见恨晚,不仅可以用作前端的view,作为报表模板也很好用,实践中觉得这个模板引擎还是蛮好用的。在非web的环境中使用过程是初始化参数、取得velocity引擎、取得velocity模板、取得velocity的上下文context、把数据填充到模板中,输出模板。可以参考 http://hi.baidu.com/mmfveuwtailmoxe/item/53defedf7d57e538e3108f80 里面介绍得简单明了
一:定义模板文件 helloVelocity.vm (要放在类路径下)
一下内容就是一个模板,可以写为一个.vm文件保存在项目中
# # {单据责任人}:您的 {单据号} 号{单据类型}在 {操作日期} 日已支付
${owner}:您的 ${bill} 号${type}在 ${ date } 日已支付
双井号"##"开始是 velocity 模板的注释,与 Velocity.INPUT_ENCODING 对应,要求 helloVelocity.vm 用 GBK 字符集保存,否则出乱码。
二:加载模板,填充值,输出。 HelloVelocity.java 的代码如下
package com.unmi.velocity; import java.io.*; import java.text.*; import java.util.*; import org.apache.velocity.*; import org.apache.velocity.app.*; public class HelloVelocity { public static void main(String[] args) throws Exception { // 配置初始化参数 Properties props = new Properties(); props.setProperty(Velocity.INPUT_ENCODING, "GBK"); props.setProperty(Velocity.RESOURCE_LOADER, "class"); props.setProperty("class.resource.loader.class", "org.apache.velocity.runtime.resource.loader.ClasspathResourceLoader"); // 初始化并取得Velocity引擎 VelocityEngine ve = new VelocityEngine(props); // 取得velocity的模版 Template template = ve.getTemplate("helloVelocity.vm"); // Template实例的获取方式也可以用下面两行代码 // Velocity.init(props); // Template template = Velocity.getTemplate("helloVelocity.vm"); // 取得velocity的上下文context VelocityContext context = new VelocityContext(); // 把数据填入上下文 context.put("owner", "Unmi"); context.put("bill", "1000"); context.put("type", "报销单"); context.put("date", new SimpleDateFormat("yyyy-MM-dd HH:mm:ss") .format(new Date())); // 输出流,你可以自由控制输出到哪,String、File、Socket 等 Writer writer = new PrintWriter(System.out); // 转换输出 template.merge(context, writer); writer.flush(); } }
以上代码执行结果是在控制台下输出
Unmi:您的 1000 号报销单在 2007-06-04 21:56:13 日已支付
OK,代码应该可以说是十分清晰明了,加载模板->填充值->合并模板输出内容,这就是模板技术要做的事情。
上 面介绍的是用 ClasspathResourceLoader 方式加载模板,Velocity 还提供了其他几种 ResourceLoader: DataSourceResourceLoader, FileResourceLoader, JarResourceLoader, StringResourceLoader, URLResourceLoader。由名称我们就能知道它们是从哪加载模板,可在项目中灵活选用适合自己的 ResourceLoader(通过配置 Velocity 引擎的初始化参数)。当然,上面只是一个非常简单的例子,如果仅能完成如此之功能,肯定是用不广泛。所以 Velocity 还提供定义了一种称之为 VTL(Velocity Template Language) 的东西,支持 #if、#foreach、#set、#include、#parse、#macro 等语法能处理你更复杂的数据8028,详细语法参考 Velocity用户手册。可以定义出你想要的功能更完善的模板。他可以作为一个 view 替代 jsp。当然一家定义的 VTL 着实给学习者增加了不少难度,但当你真正喜欢上了,这些都不成问题。
有一个 Velocity Eclipse 插件,可设置 Updates Site 为 http://propsorter.sourceforge.net/veloeclipse 进行下载或更新,方便在Eclipse 中编辑 vm 文件。
你可以想想 Velocity 能为你轻松解决什么问题,如定义模板自动化生成代码,把我某个 Blog 上的所有日志依据模板生成一个 rss.xml 文件就能导入到别的博客中,与 Spring 结合使用。http://velocity.apache.org/ 上的 anakia/texen/velocity-tools 为 Velocity 扩展了更多的功能。
实践中最容易出现的错误就是加载模板(通常是.vm)文件的时候容易找不到文件。
这个问题参考 http://www.blogjava.net/sxyx2008/archive/2010/11/11/337799.html
这里列举了常用的加载方式,转过来save一下。
package com.velocity.test; import java.io.StringWriter; import java.util.Properties; import org.apache.velocity.VelocityContext; import org.apache.velocity.app.VelocityEngine; /** * 从文件中加载模板文件,即velocity默认的模板文件加载方式 * @author welcome * */ public class LoaderFromFile { public static void main(String[] args) throws Exception{ //初始化参数 Properties properties=new Properties(); //设置velocity资源加载方式为file properties.setProperty("resource.loader", "file"); //设置velocity资源加载方式为file时的处理类 properties.setProperty("file.resource.loader.class", "org.apache.velocity.runtime.resource.loader.FileResourceLoader"); //实例化一个VelocityEngine对象 VelocityEngine velocityEngine=new VelocityEngine(properties); //实例化一个VelocityContext VelocityContext context=new VelocityContext(); //向VelocityContext中放入键值 context.put("username", "张三"); context.put("password", "123456789"); context.put("age", "20"); context.put("address", "陕西西安"); context.put("blog", "http://blogjava.net/sxyx2008"); //实例化一个StringWriter StringWriter writer=new StringWriter(); //从vm目录下加载hello.vm模板,在eclipse工程中该vm目录与src目录平级 velocityEngine.mergeTemplate("vm/hello.vm", "gbk", context, writer); System.out.println(writer.toString()); } } 二、从类路径加载模板文件 package com.velocity.test; import java.io.StringWriter; import java.util.Properties; import org.apache.velocity.VelocityContext; import org.apache.velocity.app.VelocityEngine; /** * 从class(类路径)中加载模板文件 * @author welcome * */ public class LoaderFromClass { public static void main(String[] args) throws Exception{ //初始化参数 Properties properties=new Properties(); //设置velocity资源加载方式为class properties.setProperty("resource.loader", "class"); //设置velocity资源加载方式为file时的处理类 properties.setProperty("class.resource.loader.class", "org.apache.velocity.runtime.resource.loader.ClasspathResourceLoader"); //实例化一个VelocityEngine对象 VelocityEngine velocityEngine=new VelocityEngine(properties); //实例化一个VelocityContext VelocityContext context=new VelocityContext(); //向VelocityContext中放入键值 context.put("username", "张三"); context.put("password", "123456789"); context.put("age", "20"); context.put("address", "陕西西安"); context.put("blog", "http://blogjava.net/sxyx2008"); //实例化一个StringWriter StringWriter writer=new StringWriter(); //从src目录下加载hello.vm模板 //假若在com.velocity.test包下有一个hello.vm文件,那么加载路径为com/velocity/test/hello.vm velocityEngine.mergeTemplate("com/velocity/test/hello.vm", "gbk", context, writer); //velocityEngine.mergeTemplate("hello.vm", "gbk", context, writer); System.out.println(writer.toString()); } } 三、从jar文件中加载模板文件 package com.velocity.test; import java.io.StringWriter; import java.util.Properties; import org.apache.velocity.VelocityContext; import org.apache.velocity.app.VelocityEngine; /** * 从jar文件中加载模板文件 * @author welcome * */ public class LoaderFromJar { public static void main(String[] args) throws Exception{ //初始化参数 Properties properties=new Properties(); //设置velocity资源加载方式为jar properties.setProperty("resource.loader", "jar"); //设置velocity资源加载方式为file时的处理类 properties.setProperty("jar.resource.loader.class", "org.apache.velocity.runtime.resource.loader.JarResourceLoader"); //设置jar包所在的位置 properties.setProperty("jar.resource.loader.path", "jar:file:WebRoot/WEB-INF/lib/vm.jar"); //实例化一个VelocityEngine对象 VelocityEngine velocityEngine=new VelocityEngine(properties); //实例化一个VelocityContext VelocityContext context=new VelocityContext(); //向VelocityContext中放入键值 context.put("username", "张三"); context.put("password", "123456789"); context.put("age", "20"); context.put("address", "陕西西安"); context.put("blog", "http://blogjava.net/sxyx2008"); //实例化一个StringWriter StringWriter writer=new StringWriter(); //从/WebRoot/WEB-INF/lib/vm.jar中加载hello.vm模板 vm.jar的目录结构为vm/hello.vm velocityEngine.mergeTemplate("vm/hello.vm", "gbk", context, writer); System.out.println(writer.toString()); } }