技术开发 频道

Java进阶:编写自定义的Velocity指令

   首先我们定义一个这样的块指令:#cache( “ CacheRegion ” , ” Key ” ) ,其中第一个参数为缓存区域、第二个参数为对应缓存数据的键值。该指令自动将包含在指令内部的脚本执行后的结构缓存起来,当第一次请求时检查缓存中是否存在此 HTML 片段数据,如果存在就直接输出到页面,否则执行块指令中的脚本,执行后的结果输出到页面同时保存到缓存中以便下次使用。使用方法如下所示:

#cache("News","home") 
  ## 读取数据库中最新新闻并显示
  <ul> 
  #foreach($news in $NewsTool.ListTopNews(10)) 
	 <li> 
	  <span class='date'> 
 $date.format("yyyy-MM-dd",${news.pub_time}) 
 </span> 
	  <span class='title'>${news.title}</span> 
	 </li> 
  #end 
  </ul> 
 #end
 

其中 $NewsTool.ListTopNews(10) 是用来从数据库中读取最新发布的 10 条新闻信息。 

接下来我们来看 #cache 这个指令对应的源码:

/**
 * Velocity模板上用于控制缓存的指令
 * @author Winter Lau
 * @date 2009-3-16 下午04:40:19
 */
public class CacheDirective extends Directive {

    final static Hashtable<String,String> body_tpls = new Hashtable<String, String>();
	
    @Override
    public String getName() { return "cache"; } //指定指令的名称

    @Override
    public int getType() { return BLOCK; } //指定指令类型为块指令

    /* (non-Javadoc)
    * @see org.apache.velocity.runtime.directive.Directive#render()
    */
    @Override
    public boolean render(InternalContextAdapter context, Writer writer, Node node)
        throws IOException, ResourceNotFoundException, ParseErrorException,
        MethodInvocationException 
    {
        //获得缓存信息
        SimpleNode sn_region = (SimpleNode) node.jjtGetChild(0);
        String region = (String)sn_region.value(context);
        SimpleNode sn_key = (SimpleNode) node.jjtGetChild(1);
        Serializable key = (Serializable)sn_key.value(context);
     
        Node body = node.jjtGetChild(2);
        //检查内容是否有变化
        String tpl_key = key+"@"+region;
        String body_tpl = body.literal();
        String old_body_tpl = body_tpls.get(tpl_key);
        String cache_html = CacheHelper.get(String.class, region, key);
        if(cache_html == null || !StringUtils.equals(body_tpl, old_body_tpl)){
            StringWriter sw = new StringWriter();
            body.render(context, sw);
            cache_html = sw.toString();
            CacheHelper.set(region, key, cache_html);
            body_tpls.put(tpl_key, body_tpl);
        }
        writer.write(cache_html);
        return true;
    }
}

 

0
相关文章