新版Dlog4J絕大部分改用了Velocity來充當View展示層,此中也累積了幾點印象深刻的經驗,在這里做個簡單的介紹:
1)嵌套vm
2)內置對象
3)taglib的改造
4)vm的reload問題
5)exception處理問題
6)數(shù)組的訪問
1)嵌套vm,在vm中可使用#parse來嵌套另外一個vm,對應的在jsp方面就是嵌套jsp,但嵌套在內的jsp和外部的jsp無法共用變量,非常不方便,而velocity不存在這方面的問題,變量完全共享,如:
->a.vm 里嵌套 b.vm;
->a.vm 里定義了變量 $param;
->b.vm 里可以直接使用$param,無任何限制。
但需要特別注意的是,如果b.vm里同時定義有變量$param,則b.vm里將使用b.vm里定義的值;
2)內置對象
Velocity內置了一些對象,在vm模版里可以直接調用,列舉如下:
$request、$response、$session,另外,模板內還可以使用 $msg內的消息工具訪問 Struts 的國際化資源,達到簡便實現(xiàn)國際化的方法。
3)taglib的改造
taglib是Struts中一個重要的功能,但也有不足之處,后繼參與開發(fā)和維護的人員不能很容易的掌握其作用,以及這些特殊的標簽容易使頁面的美工設計人員不容易處理等等。
如果原來View層編碼規(guī)范,在jsp中出現(xiàn)的java代碼比較少或者沒有,則改造到Velocity也就比較容易。
替代taglib的方法很多,也很簡便,比如Macro宏,類似JavaBean的使用方式等,而Dlog4J采用了綜合的方法,具體說就是使用 ObjectTools extends VelocityTool,并在Velocity的配置文件velocity-toolbox.xml中配置好在模版上的變量名,進而所有的vm模版都可以直接使用ObjectTools,vm模版全部通過ObjectTools來統(tǒng)一訪問DAO進而讀取數(shù)據(jù)展示。
4)vm的reload問題
有時會發(fā)現(xiàn)vm模版修改后進行新請求時,頁面會繼續(xù)采用更改前的模版,這是因為模版的加載是有一定時間間隔的,如要更改立即生效,需要在velocity-(*).jar 包中,找到\org\apache\velocity\runtime\defaults 目錄,更改Velocity默認的配置文件:velocity.properties,修改如下2項:
file.resource.loader.cache,模版文件是否進行緩沖
file.resource.loader.modificationCheckInterval,模版資源的修改檢測間隔。
用rar把velocity-(*).jar 解壓,得到資源文件后修改再更新回.jar 內。
5)exception處理問題
由于與Struts結合,使用了Velocity工具包:velocity-tools-1.1.jar,其中的org.apache.velocity.tools.view.servlet.VelocityViewServlet 是默認的Velocity處理引擎,所有的異常處理也都交到VelocityViewServlet的error方法處理,沒有類似jsp的 errorPage,所以不能對異常進行方便的包裝,所以要想封裝exception,只有通過改造VelocityViewServlet來實現(xiàn)。
Dlog4J中增加了dlog4j.VelocityServlet,繼承VelocityViewServlet并覆蓋了error的處理辦法,從而實現(xiàn)對異常的封裝和包裹。
6)數(shù)組訪問
對數(shù)組的訪問在Velocity中存在問題,因為Velocity只能訪問對象的方法,而數(shù)組又是一個特殊的Array,所以雖然數(shù)組可以進行循環(huán)列舉,但卻不能定位訪問特定位置的元素,如 strs[2],數(shù)組對固定位置元素的訪問調用了Array的反射方法get(Object array, int index),而Velocity沒能提供這樣的訪問,所以數(shù)組要么改成List等其他類容器的方式來包裝,要么就通過公用Util類的方式來提供,傳入數(shù)組對象和要訪問的位置參數(shù),從而達到返回所需值的目的。
另外在這里值得一提的是,F(xiàn)reeMarker在模板方面,比Velocity有了更多的改進,包括在數(shù)組處理方面提供:使用類似[i]語法的索引方式訪問數(shù)組元素,以及可以查詢數(shù)組長度。