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變量,該內容也會被處理,因此需要變量名唯一























發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章