velocity技术实现页面静态化

来源:互联网 发布:java过滤特殊字符xss 编辑:程序博客网 时间:2024/06/06 20:08
以前参与过的一个电商网站用Velocity技术实现了商品页面静态化,这门技术适用于页面不怎么变化,形式单一的地方。下面的例子是关于这门技术的详细知识。

这里采用编程式配置,因为采用properties文件的形式配置会写一些具体的系统地址,这样对于程序的可移植性不是很好,所以我采用了编程式配置。

首先,我的项目组织结构以及所需jar包,如下图:


velocity技术实现页面静态化


创建一个测试类,具体说明在代码注释里,代码如下:


public class VelocityDemo {/** * 配置Velocity的一些属性 */@BeforeClasspublic static void init() {try {Properties prop = new Properties();//指定日志文件存放位置prop.put("runtime.log", "src/log/velocity.log");//指定模板文件存放位置prop.put("file.resource.loader.path", "src/vm");//指定输入编码格式prop.put("input.encoding", "UTF-8");//指定输出编码格式prop.put("output.encoding", "UTF-8");//修改获取迭代索引的名称,默认为velocityCountprop.put("directive.foreach.counter.name", "index");//修改迭代索引的初始值,默认为1prop.put("directive.foreach.counter.initial.value", "0");Velocity.init(prop);} catch (Exception e) {e.printStackTrace();}}@Testpublic void produceStaticFile() throws Exception {//VelocityContext这个类按照我的理解与request的作用是一样的VelocityContext context = new VelocityContext();//创建一个集合并放入context范围内List<String> list = new ArrayList<String>();list.add("one");list.add("two");context.put("list", list);//创建一个Map并放入context范围内Map<Integer,String> map = new HashMap<Integer, String>();map.put(1, "one");map.put(2, "two");context.put("map", map);//把一个布尔值放入contextcontext.put("flag", true);//把当前日期放入contextcontext.put("now", new Date());//把本类的对象放入context,为了使用formatDate方法context.put("obj", new VelocityDemo());//放一个null值为了验证表达式为null时将输出什么context.put("null", null);//取得给定位置的模板Template template = Velocity.getTemplate("velocity.vm");    //定义生成的html文件File file = new File("html/velocity.html");if(!file.getParentFile().exists()) file.getParentFile().mkdirs();FileOutputStream fos = new FileOutputStream(file);OutputStreamWriter osw = new OutputStreamWriter(fos, "UTF-8");BufferedWriter bw = new BufferedWriter(osw);//模板与context里的属性相结合写入输出流中template.merge(context, bw);bw.close();}/** * 扩展Velocity的功能,把给定的日期按照给定的格式转换成字符串 * @param format  日期格式 * @param date    日期 * @return   格式化后的日期 */public String formatDate(String format,Date date) {SimpleDateFormat dateMat = new SimpleDateFormat(format);return dateMat.format(date);}}

velocity.vm代码如下:


<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"><html>  <head>    <title>Velocity demo</title>    <meta http-equiv="Content-Type" content="text/html; charset="utf-8" />  </head>    <body>    <h1>迭代集合</h1>    #foreach($i in $list)    $index   $i    #end    <br/>    <hr/>        <h1>迭代Map的两种方式,Velocity表达式支持调用对象的方法</h1>    #foreach($key in $map.keySet())$key = $map.get($key)#end#foreach($entry in $map.entrySet())$entry.getKey() = $entry.getValue()#end<br/>    <hr/>        <h1>赋值</h1>    #set($name = "hxl")    $name        <br/>        赋值数组    #set($name = ["one","two"])    #foreach($i in $name)    $i    #end    <br/>    如果是连着的数字,例如:1,2,3,4,5,6;可以这样赋值:    #set($name = [1..6])  #set($reverse = [6..1])    #foreach($i in $name)    $i    #end    <br/>    #foreach($i in $reverse)    $i    #end    <br/>    <hr/>        <h1>if else 语句</h1>    #if($flag)     成立    #else     不成立    #end         <br/>    <hr/>    <h1>格式化日期</h1>    $now   <br/>    $obj.formatDate("yyyy-MM-dd",$now)         <br/>    <hr/>         <h1>如果为null将输出空字符串</h1>        这是原本为null是输出的值  $null  <br/>        这是判断以后的值                $!null  </body></html>

这门技术说的通俗一点就是把这个给定的模板(这个模板里面嵌入一些表达式,从而生成动态数据)转换成静态html页面。

那么,难题出现了,既然这个页面为静态的,我怎么才能统计这个页面的点击量呢?其实也很简单:有两种方法可以实现。

1)<img src="" width="0" height="0" /> 利用src属性访问统计点击量的路径

2)用body标签的onload事件,用Ajax发送post请求。

推荐用第一种方式,因为如果客户端禁用js会使第二种方式失效。

0 0