VTL中有三种references:
变量引用(variables),
属性引用(properties)
命令引用(methods).
做为一个使用VTL的设计者, 你和你的java软件工程师必须就模板中引用的特定名了(就是$后的名字)达成一致的协议!这样,模板和java代码才可按照你们的意图去结合以输出正确的内容.
所有的引用在模板中都表现为一个字符串. 假设一个引用变量 $foo 的值事实上是一个int, Velocity engine在处理时将调用它的.toString() 去解析这个字符串所代表的对象(int).
简单的说变量以"$" 开后,后面跟一个VTL指示符( Identifier).一个合法的VTL指示符是以字母开头,后面可以是以下任意字符:
Alphabetic (a ... z, A ... Z)
Numeric (0. 9)
Hyphen ("-")
Underscore ("_")
以下是正确的VTL变量名:
$foo
$mudSlinger
$mud-slinger
$mud_slinger
$mudSlinger1
当VTL中的一个变量如 $foo, 这个变量可以在模板中提取它自己的值通过set 指示符,或者从java代码中.比如,如果需java中的变量foo的值为bar,给模板中所有输出$foo声明的值都成为bar.当然,在模板中使用如下VTL也可以达到这个目地。
#set( $foo = "bar" )
VTL的第二种引用,属性引用,注意”属性”具有相对固定的格式. 它也是以$开头的合法VTL指示符,随后是”变量名字.变量属性”. 如下例:
$customer.Address
$purchase.Total
第一个例子, $customer.Address.我们设想可能在两种意思.首先它可能在查找customer引用的一个hashtable中的以“Address”为key关联的一个数据对象.另外他可能表示的是java对象customer中的getAddress()这个命令取得的结果(当然也可写成 $customer.getAddress()). 当客户请求Web页面中Velocity将根据具体的customer类型输出.
在java 代码中定义命令是最通常的事, 像执行一组方程式计算成本,读取一个文件等. 命令引用和其它引用一个也是一个一般的VTL声明,看如下的例子可能会更快的理解:
$customer.getAddress()
$purchase.getTotal()
$page.setTitle( "My Home Page" )
$person.setAttributes( ["Strange", "Weird", "Excited"] )
前两个例子 -- $customer.getAddress() and $purchase.getTotal() – 可以等同与属性引用情况: $customer.Address and $purchase.Total. 如你猜对了这点,呵,你还蛮聪明!同时,他们是等同与java对象coustomer的getAddress()命令调用。 后面两个引用呢,也会直接对应java对象的对应命令,不同的是传入了命令参数。
前己提及,属性可以引用到对象的命令. Velocity会使用合适的策略选择引用到的命令. 它会根据协定的命令命令格式查找. 无论属性引用的的名字是否大小写,Velocity都有固定的查找规则.如在$customer.address引用时,查找顺序是:
1. getaddress()
2. getAddress()
3. get("address")
4. isAddress()
对于VTL中大写的属性名Address引用,将是:
1. getAddress()
2. getaddress()
3. get("Address")
4. isAddress()
小结一下:
对于之前写到的Velocity与servlet整合的小例子
代码是这样写的:
#foreach($book in $!{list})
$!{velocityCount}
$!{book.id}
$!{book.name}
$!{book.author}
<br>
#end
这些都是对属性的引用,当然把它改写为方法的引用也是可以的
#foreach($book in $!{list})
$!{velocityCount}
$!{book.getId()}
$!{book.getName()}
$!{book.getAuthor()}
<br>
#end
这样也是可以的
以上是简洁格式引用的介绍,规则的格式像下面,如你看到的变量名需要放到{}中:
${mudSlinger}
${customer.Address}
${purchase.getTotal()}
大多数情况下,简洁格式引用足以满足使用,但有些情况下,必须使用正规格式引用.
假设你构造的一个字符串中要包括有 $vice 变量的值. 你觉得以下两种写法会是同样的结果吗:
1.Jack is a $vicemaniac.
2.Jack is a ${vice}maniac.
这样,Velocity就知你要的是 $vice, 而不是 $vicemaniac变量,正规引用格式一般用于在模板中直接调整字符串内容.
Velocity遇到一个不能处理的引用时,一般他会直接输出这个引用$email的写法,页面上会看到的是$email,如下例,
我们可以在$后面加上一个!号!!!!!!!,那么就会输出空白:.
<input type="text" name="email" value="$email"/>
<input type="text" name="email" value="$!email"/>
正式的写法是:.
<input type="text" name="email" value="$!{email}"/>
至此,你对velocity的refenerce己比较熟悉了, 你可以在你的模板中开始应用这些功能. 但你还可以知道的是Velocity references从java语法中汲取了一些优点以便模板设计者更容易使用VTL.比如:
$foo
$foo.getBar()
## 等同于
$foo.Bar
$data.setUser("jon")
##等同于
#set( $data.User = "jon" )
$data.getRequest().getServerName()
##等同于
$data.Request.ServerName
## is the same as
${data.Request.ServerName}
这里示例了你可选的一些引用方式. VTL汲取了java语法和java bean的一些简洁语法以解析java代码中Context中的对象和这些对象的命令及属性---这样,一个java对象的所有功能都可以展示到视图中了.
Velocity也借见了java Bean的规范(Bean specifications defined by Sun Microsystems), 是大小写敏感的; 但Velocity会尽可能的帮你修正错误. 当命令 getFoo() 通过指令 $bar.foo在模板中引用时,Velocity的搜索规则我们在前面己讲了,你还记得是什么吗?.
注意:模板中引用的必须是通过java Bean中的getter/setter 实现的,而直接的java对象的数据域是不能直接引用的,如$foo.Name 会解析到 class Foo's getName() 的实例方法,但不会解析到Foos类的 public Name 这个实例变量.