velocity源码分析:事件处理

velocity提供了一些扩展点,如: 指令扩展、事件处理等。本文主要阐述基于事件处理的扩展,并提供一些事例。

本文讨论的velocity版本如下:

URL: http://svn.apache.org/repos/asf/velocity/engine/trunk
Repository Root: http://svn.apache.org/repos/asf
Repository UUID: 13f79535-47bb-0310-9956-ffa450edef68
Revision: 1221660
Node Kind: directory
Schedule: normal
Last Changed Author: nbubna
Last Changed Rev: 1221053
Last Changed Date: 2011-12-20 08:55:01 +0800 (Tue, 20 Dec 2011)

类图:



velocity中提供了一些事件处理扩展:

IncludeEventHandler
InvalidReferenceEventHandler
MethodExceptionEventHandler
ReferenceInsertionEventHandler
本文先简单介绍各个扩展点,最后重点介绍ReferenceInsertionEventHandler


1.IncludeEventHandler(#include()和#parse()对应事件的接口类):

    默认实现主要有两个,IncludeNotFound和IncludeRelativePath

    IncludeNotFound在#include(x)和#parse(x)加载x之前操作,返回具体的x给指令加载

        若x存在,返回x;

        若x不存在则返回配置的eventhandler.include.notfound属性对应的模板文件;

        若eventhandler.include.notfound对应的文件也不存在直接记录log;

具体代码如下:


IncludeRelativePath在#include(x)和#parse(x)加载x之前操作,返回具体的x给指令加载

   增加了相对模板路径的文件加载,避免文章太长,代码不给出了。


2.InvalidReferenceEventHandler(对无效比较的错误提示):

    主要在get,set以及其他方法调用时出现细化错误(ParseErrorException)提示内容,当然这个错误是根据eventhandler.invalidreference.exception的设置是否抛出,默认不抛出。


3.MethodExceptionEventHandler(对会抛出异常的方法调用时作友好性处理):

    目前实现有两个类:ExceptionGeneratingEventHandler、PrintExceptions,主要对异常作些友好性处理。


以上三个点更接近系统内部的一些规则处理,可扩展性不大,如果使用到,默认实现基本足够,因此不做细讲,我们重点讨论最后一种。


4.ReferenceInsertionEventHandler(变量结果写入事件处理);

    这个比较有用是对渲染结果的处理,比如html,javascript,url,java,sql,xml等,这些是比较实用的功能。velocity默认提供了替换html,javascript,java,sql,xml的过滤扩展。

   目前定义了四个实现:

    EscapeReference                             escape抽象类,定义公共的外部属性读入和接口

    EscapeHtmlReference                    过滤html标签,配置属性eventhandler.escape.html.match,实现类StringEscapeUtils.escapeHtml()

    EscapeJavaScriptReference          过滤javascript标签,配置属性eventhandler.escape.javascript.match,实现类StringEscapeUtils.escapeJavaScript()

    EscapeSqlReference                       过滤sql标签,配置属性eventhandler.escape.sql.match,实现替换'为‘’(单引号替换为双引号)

    EscapeXmlReference                      过滤xml,配置属性eventhandler.escape.xml.match,具体实现类StringEscapeUtils.escapeXml

如果自己要扩展,除了配置多个Reference外也可以采用一个Reference多个条件处理,如果和macros集合,效果会更好,

比如:定义一个宏:

#macro(URL $url_escape_z)
    $url_escape_z
#end

我们可以在页面中如下使用

#URL("a&=<>?b")

若在velocity.properties属性中配置对应的过滤器为EscapeURLReference,那么代码在解析时会把#URL()中的变量改成url格式输出。


需要说明的是:

    调用到EscapeURLReference并非是#URL标签,而是$url_escape_z

    即便是$!url_escape_z活${url_escape_z}活$!{url_escape_z}都不会处理

    #URL指令之所以会处理,是因为和对应变量挂钩

   若自己在代码中有$url_escape_z变量,该内容也会被处理,因此需要变量名唯一























  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值