最近重构,期间也看《汉武大帝》,但冬冬不好这口,为此经常给他催到找牙,但他好厅长那口,似乎是没完没了,也是,这不年底都到了。
新版Dlog4J绝大部分改用了Velocity来充当View展示层,此中也累积了几点印象深刻的经验,在这里做个简单的介绍:
1)嵌套vm
2)内置对象
3)taglib的改造
4)vm的reload问题
5)exception处理问题
6)数组的访问
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 的国际化资源,达到简便实现国际化的方法。
3)taglib的改造
taglib是Struts中一个重要的功能,但也有不足之处,后继参与开发和维护的人员不能很容易的掌握其作用,以及这些特殊的标签容易使页面的美工设计人员不容易处理等等。
如果原来View层编码规范,在jsp中出现的java代码比较少或者没有,则改造到Velocity也就比较容易。
替代taglib的方法很多,也很简便,比如Macro宏,类似JavaBean的使用方式等,而Dlog4J采用了综合的方法,具体说就是使用 ObjectTools extends VelocityTool,并在Velocity的配置文件velocity-toolbox.xml中配置好在模版上的变量名,进而所有的vm模版都可以直接使用ObjectTools,vm模版全部通过ObjectTools来统一访问DAO进而读取数据展示。
4)vm的reload问题
有时会发现vm模版修改后进行新请求时,页面会继续采用更改前的模版,这是因为模版的加载是有一定时间间隔的,如要更改立即生效,需要在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来实现。
Dlog4J中增加了dlog4j.VelocityServlet,继承VelocityViewServlet并覆盖了error的处理办法,从而实现对异常的封装和包裹。
6)数组访问
对数组的访问在Velocity中存在问题,因为Velocity只能访问对象的方法,而数组又是一个特殊的Array,所以虽然数组可以进行循环列举,但却不能定位访问特定位置的元素,如 strs[2],数组对固定位置元素的访问调用了Array的反射方法get(Object array, int index),而Velocity没能提供这样的访问,所以数组要么改成List等其他类容器的方式来包装,要么就通过公用Util类的方式来提供,传入数组对象和要访问的位置参数,从而达到返回所需值的目的。
另外在这里值得一提的是,FreeMarker在模板方面,比Velocity有了更多的改进,包括在数组处理方面提供:使用类似[i]语法的索引方式访问数组元素,以及可以查询数组长度。