使用Velocity实现页面静态化
使用Velocity实现页面静态化velocity下载地址:http://velocity.apache.org/download.cgi用到的jar文件:velocity-1.7-dep.jar\lib\log4j-1.2.12.jar如果不使用velocity-1.7-dep.jar,也可以使用velocity-1.7.jar,但这时需要把\lib下的commons-collections-3.2.1.jar 、commons-lang-2.4.jar 和 oro-2.0.8.jar放入类路径下。velocity-1.7-dep.jar 文件内部已经包含前面三个jar文件的类。 使用Velocity的配置:在类路径下加入velocity.properties,内容如下:# 指定日志文件存放位置runtime.log=D:\\Java\\Velocity\\velocity_emample.log# 指定模板文件加载位置file.resource.loader.path=D:\\Java\\Velocity\\vm# 指定输入编码格式input.encoding=UTF-8# 指定velocity的servlet向浏览器输出内容的编码default.contentType=text/html;charset\=UTF-8#指定输出编码格式output.encoding=UTF-8D:\Java\Velocity\为当前工程所在目录。新建Folder名称为vm,新建模板名称为helloWorld.vm,修改编码为UTF-8,因为velocity.properties中的编码指定了为UTF-8,需要一致。VelocityTest.java:package junit.test;import java.io.BufferedWriter;import java.io.File;import java.io.FileOutputStream;import java.io.OutputStreamWriter;import java.io.StringWriter;import java.util.Date;import java.util.HashMap;import java.util.Map;import java.util.Properties;import org.apache.velocity.Template;import org.apache.velocity.VelocityContext;import org.apache.velocity.app.Velocity;import org.junit.BeforeClass;import org.junit.Test;import cn.itcast.bean.Person;import cn.itcast.bean.Product;import cn.itcast.utils.DateTool;public class VelocityTest { @BeforeClass public static void setUpBeforeClass() throws Exception { // 初始化velocity // 方式1:从配置文件中初始化 //Velocity.init("src/velocity.properties"); // 方式2:基于编程方式初始化 Properties properties = new Properties(); // 指定日志文件存放位置 properties.put("runtime.log", "D:\\Java\\Velocity\\velocity_emample.log"); // 指定模板文件加载位置 properties.put("file.resource.loader.path", "D:\\Java\\Velocity\\vm"); // 指定输入编码格式 properties.put("input.encoding", "UTF-8"); // 指定velocity的servlet向浏览器输出内容的编码 properties.put("default.contentType", "text/html;charset\\=UTF-8"); // 指定输出编码格式 properties.put("output.encoding", "UTF-8"); // 迭代索引名 properties.put("directive.foreach.counter.name", "index"); // 迭代开始的下标 properties.put("directive.foreach.counter.initial.value", 0); Velocity.init(properties); } // Example 1: 简单取值 // ${helloWorld} @Test public void helloWorld() { try { VelocityContext context = getContext(); context.put("helloWorld", "你好,传智播客"); // 在上下文中存入值,则可在模板中使用该属性的值 Show(context, "helloWorld.vm"); } catch (Exception e) { e.printStackTrace(); } } // Example 2: 访问复合类型 // ${person.personid} : ${person.name} @Test public void accessJavaBean() { try { VelocityContext context = getContext(); context.put("person", new Person(888, "人员姓名")); Show(context, "person.vm"); } catch (Exception e) { e.printStackTrace(); } } // Example 3: 迭代集合 // #foreach($person in $persons) // $person.personid : $person.name // #end @Test public void loopList() { try { VelocityContext context = getContext(); context.put("persons", new Person[]{new Person(888, "老张"), new Person(999, "老王")}); Show(context, "persons.vm"); } catch (Exception e) { e.printStackTrace(); } } // Example 4: 迭代Map, 对velocity表达式支持对象方法的访问 // 下面演示map的两种迭代方式,与Java语法中相同: // #foreach($key in $maps.keySet()) // $key : $maps.get($key) // #end // -------------------- // #foreach($entry in $maps.entrySet()) // $entry.getKey() : $entry.getValue() // #end // Example 5: 当前索引 // 下面演示索引: // #foreach($entry in $maps.entrySet()) // $velocityCount= $entry.getKey() : $entry.getValue() // #end // vilocityCount变量名可以通过directive.foreach.counter.name属性修改。 // 迭代的索引默认从1开始,可以通过directive.foreach.counter.initial.value=0属性修改 // # 迭代索引名 // directive.foreach.counter.name=index // # 迭代开始的下标 // directive.foreach.counter.initial.value=0 // 下面演示索引: // #foreach($entry in $maps.entrySet()) // $index= $entry.getKey() : $entry.getValue() // #end // 输出: // 下面演示索引: // 0= 第二 : 老王 // 1= 第一 : 老张 @Test public void loopMap() { try { VelocityContext context = getContext(); Map<String, String> maps = new HashMap<String, String>(); maps.put("第一", "老张"); maps.put("第二", "老王"); context.put("maps", maps); Show(context, "maps.vm"); } catch (Exception e) { e.printStackTrace(); } } // Example 6: 在模板中进行赋值 // 变量赋值: // // 字符串赋值("" 或 ''): // #set($name="老张") // $name 或 ${name} // // 数值赋值: // #set($age=30) // $age // // 数组赋值: // 1. 输出1~10 // #set($ints=[1..10]) // #foreach($entry in $ints) // $entry // #end // 2. 输出10~1 // #set($ints=[10..1]) // #foreach($entry in $ints) // $entry // #end // 3. 输出1、10 // #set($ints=[1,10]) // #foreach($entry in $ints) // $entry // #end // 4. 输出abc、def // #set($strs=["abc","def"]) // #foreach($entry in $strs) // $entry // #end @Test public void pageset() { try { VelocityContext context = getContext(); Show(context, "pageset.vm"); } catch (Exception e) { e.printStackTrace(); } } // Example 7: if 条件判断 // #if($bool) // bool 为true // #else // bool 为false // #end @Test public void ifstat() { try { VelocityContext context = getContext(); context.put("bool", false); Show(context, "condition.vm"); } catch (Exception e) { e.printStackTrace(); } } // Example 8: 格式化日期 // 未格式化的:${now} // 格式化的:$dateTool.format("yyyy-MM-dd HH:mm:ss", $now) // 输出: // 未格式化的:Wed Oct 26 09:56:47 CST 2011 // 格式化的:2011-10-26 09:56:47 @Test public void formatDate() { try { VelocityContext context = getContext(); context.put("now", new Date()); // 扩展velocity的功能 context.put("dateTool", new DateTool()); Show(context, "date.vm"); } catch (Exception e) { e.printStackTrace(); } } // Example 9: 输出到文件 @Test public void outFile() { try { VelocityContext context = getContext(); //Product product = new Product(888, "瑜伽球", "非常好的瑜伽球"); Product product = new Product(888, "瑜伽球", null); // 注意:如果未给product.note赋值,则生成文件时会将代码原样输出 // Product product = new Product(888, "瑜伽球", null); // 在使用时加上“!”:$!{product.note},如果为空时就不输出 context.put("product", product); Show(context, "productTemplate.html"); // 输出到文件 File saveFile = new File("html/product.html"); if (!saveFile.getParentFile().exists()) { saveFile.getParentFile().mkdirs(); } FileOutputStream outStream = new FileOutputStream(saveFile); OutputStreamWriter outStreamWriter = new OutputStreamWriter(outStream, "UTF-8"); Template template = Velocity.getTemplate("productTemplate.html"); BufferedWriter writer = new BufferedWriter(outStreamWriter); //template.merge(context, outStreamWriter); template.merge(context, writer); writer.flush(); writer.close(); } catch (Exception e) { e.printStackTrace(); } } private VelocityContext getContext() { //Velocity.init("src/velocity.properties"); VelocityContext context = new VelocityContext(); // 上下文,类似 // request.setAttribute("person", // "liming"); return context; } private void Show(VelocityContext context, String vm) { Template template = Velocity.getTemplate(vm); StringWriter writer = new StringWriter(); template.merge(context, writer); System.out.println(writer.toString()); }}Person.java:package cn.itcast.bean;public class Person { private Integer personid; private String name; public Person(Integer personid, String name) { super(); this.personid = personid; this.name = name; } public Integer getPersonid() { return personid; } public void setPersonid(Integer personid) { this.personid = personid; } public String getName() { return name; } public void setName(String name) { this.name = name; }}Product.java:package cn.itcast.bean;public class Product { private Integer id; private String name; private String note; public Product() { } public Product(Integer id, String name, String note) { super(); this.id = id; this.name = name; this.note = note; } public Integer getId() { return id; } public void setId(Integer id) { this.id = id; } public String getName() { return name; } public void setName(String name) { this.name = name; } public String getNote() { return note; } public void setNote(String note) { this.note = note; }}DateTool.java:package cn.itcast.utils;import java.text.SimpleDateFormat;import java.util.Date;public class DateTool { public String format(String formatstr, Date date) { SimpleDateFormat dateFormat = new SimpleDateFormat(formatstr); return dateFormat.format(date); }}velocity.properties:# 指定日志文件存放位置runtime.log=D:\\Java\\Velocity\\velocity_emample.log# 指定模板文件加载位置file.resource.loader.path=D:\\Java\\Velocity\\vm# 指定输入编码格式input.encoding=UTF-8# 指定velocity的servlet向浏览器输出内容的编码default.contentType=text/html;charset\=UTF-8#指定输出编码格式output.encoding=UTF-8# 迭代索引名#directive.foreach.counter.name=index# 迭代开始的下标directive.foreach.counter.initial.value=0vm\productTemplate.html:<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd"><html><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8"><title>${product.name} --巴巴运动网</title></head><body> <h1>${product.name}</h1><br/> 商品说明:<br/> <div>$!{product.note}</div></body></html>