您的位置:首页 > 其它

velocity源码分析:事件处理

2012-08-07 11:25 363 查看
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变量,该内容也会被处理,因此需要变量名唯一
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: