Velocity总结
1、In Action
(1)创建基于Velocity的web应用包含两个步骤:
a、创建velocity模板,即*.vm文件。(在VTL,即velocity模板语言中,$表示跟随其后的字符串为变量。)
b、创建扩展VelocityServlet的servlet类。(loadConfiguration()、handleRequest())
(2)发布基于Velocity的web应用
webapp目录
.vm文件 WEB-INF目录
web.xml classes目录 lib目录
2、TIPS
(1)Velocity模板引擎使html页面可以引用java对象,实现了页面和程序的分离。
常见的用法有指令和引用:
指令:模板定义或自定义宏,如#set、#if、#foreach、#macro。
引用:context中的内容。$aaa $!aaa /$aaa。
(2)Velocity是一个基于java的模板引擎。网页开发者通过velocity模板语言定义模板,开发人员通过编写程序代码设置context,它包含了用于填充模板的数据。Velocity引擎将模板和context合并起来,生成动态网页。
(3)在VTL中,##表示单行注释,#* *#表示多行注释。
正式引用符:${}。
<input type="text" name="email" value="${email}"> ,当表单初次装入时,引用变量${email}没有值。velocity将在文本框中直接显示${email}字符串。若希望显示一个空白域而不是${email}字符串,使用$!{email}。
转义符\。在VTL中,$具有特殊含义。若希望$作为普通的字符来处理,应采用\$的形式。
velocity将\\解析为\,此时\是普通字符,没有转义的含义。
(4)给引用变量,如$a,赋值:
a、在Java代码中,给变量赋值用context;
b、在模板中,通过#set指令给变量赋值。如:
#set($a="aaa")
the output is $a。
或#set($monkey.Say=["not", "fault"]) ##ArrayList
或#set($monkey,Map={"banana":"good", "beef":"bad"}) ##Map
给引用属性,如$client.phone,赋值:
a、在java代码中,将属性保存在HashMap中,HashMap放在context对象中。如:
HashMap client = new HashMap();
client.put("phone", "123");
context.put("client", client);
b、定义一个javabean,再将此类的对象保存在context中。如:
client类有phone属性,
client.setPhone("123");
context.put("client", client);
方法引用,如:$client.getName()。其中client表示一个javabean。此方法引用可以缩写成属性引用。
方法引用和属性引用的主要区别是方法引用可以指定参数列表。
(5)指令(通过引用来输出动态网页内容,用指令来控制外观和内容)
#set:用来为引用变量或引用属性赋值。如:#set($money.say=["not", "fault"])。若赋值表达式的右边的取值为null,velocity不会将其赋值给左边的引用变量。
使用set指令,在双引号中的字符串将被解析。当字符串括在单引号中时,将不被解析。
如:#set($foo="bar")
${foo},输出结果为bar。
#set($b="$foo")
${b},输出结果为bar。
#set($b='$foo')
${b},输出结果为$foo。
#if:当#if指令中的条件为真时,velocity将输出#if代码块包含的文本。如:
#if($foo)
...
#end
if条件为真:
a、$foo是逻辑变量,值为true;
b、$foo的值非空。
if条件表达式中,velocity支持3种比较运算。即字符串比较(==)、对象比较(==)和整数比较。
对象比较时,只有当==两边的引用变量引用同一个对象时才为true。
#foreach:
#foreach($client in $clientList )
$velocityCount——>$client.name
#end
循环遍历$clientList列表中的所有client对象,每经过一次循环,将从$clientList列表中取得一个对象,将其赋值给$client变量。其中$clientList变量的类型可以是Array、List、Set、HashMap等。
若$allProducts是HashMap对象,则:
#foreach($key in $allProducts.keySet() )
$key——>$allProducts.get($key)
#end
$velocityCount是Velocity表示循环计数的内部变量,缺省开始值为1.该设置在velocity.properties文件中定义。
#include:用来导入本地文件,这些文件将插入到模板中#include指令被定义的地方。导入的文件内容不会被模板引擎解析。一次可以导入多个文件,文件名之间用逗号分隔,通常使用变量引用来代替文件名。
#include指令引用的文件名放在双引号内。
如:#include("green.txt", $season)
#parse:可把其它文件导入到当前模板中。#parse指令能解析被导入的文件。其中导入的文件必须放在TEMPLATE_ROOT目录下,且一次只能导入一个文件。
允许在velocity模板中嵌套执行#parse指令。最大深度由velocity.properties文件中的parse_directive.maxdepth定义。
#stop:停止模板引擎的执行并返回。在debug时很有用。
#macro:允许在VTL模板中定义重复的段。
将模板中重复的代码定义在一个velocity宏中。在模板中,所有出现重复代码的地方都可用宏来代替。
宏的定义,如:(velocity宏被命名为macroname)
#macro(macroname)
<tr><td></td></tr>
#end
在velocity模板的其它地方,调用宏的形式为:#marconame().
当模板被调用时,velocity将把#macroname()替换为:<tr><td></td></tr>
宏可以有0或多个参数,如:
#macro(tablerows $color $somelist)
#foreach($something in $somelist)
<tr><td bgcolor=$color>$something</td></tr>
#end
#end
这个叫tablerows的宏带2个参数:color和array。对tablerows宏的调用:
#set($greatlakes=["aaa", "bbb", "ccc"])
#set($color="blue")
<table>
#tablerows($color $greatlakes)
</table>
输出为:
<tr><td bgcolor="blue">aaa</td></tr>
<tr><td bgcolor="blue">bbb</td></tr>
<tr><td bgcolor="blue">ccc</td></tr>
宏可以在VTL模板中定义为inline,这样对其它的VTL模板是无效的;要使宏在所有VTL模板中共享,可以将宏定义在宏模板库(全局)中。
宏属性在velocity.properties文件中定义。如:
velocimacro.library=VM_global_library.vm ##定义逗号分隔的宏全局模板库,缺省是VM_global_library.vm,可以增加自定义的模板库。
velocimacro.permissions.allow.inline=true ##指定是否允许在VTL模板中定义宏,缺省是true,表示允许。
velocimacro.permissions.allow.inline.to.replace.global=false ##指定是否允许inline定义的宏替换同名的全局宏,缺省是false。
velocimarco.permissions.allow.inline.local.scope=false ##指定inline定义是否是定义的模板中可见,缺省是false。
velocimarco.context.localscope=false ##指定context内容是否是本地范围的,缺省是false;若为true,则使用#set指令对context做的修改只在本地范围有效,不会永久性的影响context。
velocimacro.library.autoreload=false ##指定是否自动装载宏模板库,缺省是false;若设为true,则在调用宏模板库中的宏时,会检查模板库是否更新,并在需要时重新装载;使用前提是file.resource.loader.cache=false;该属性应该在开发时使用,而不是产品阶段。
宏必须在第一次使用之前进行定义。因此#parse指令包含inline定义的宏的模板会有问题。解决方法是将宏定义到模板库中,以便velocity启动时装载。
宏不能作为参数传递给另一个宏。如:
#center(#bold("hello")) ##error
#center("#bold('hello')") ##right
引用作为宏的参数时,是使用by name形式的,表示在宏内部每次使用时才会获得其值。
在VTL中,若要串联字符串,只需要把这些字符串放在一起。
(6)
3、PS
(1)
(2)