例示velocity模板语言中的一些陷阱
objects, strings, quotes
#set ($var = $list) $var.class, $var
## java.util.List, list.toString()
#set ($var = ‘$list’) $var.class, $var
## java.lang.String, "$list"
#set ($var = "$list") $var.class, $var
## java.lang.String, list.toString()
———————————
public field not treated as property
$publicFieldBean.publicField
##won’t work; velocity doesn’t recognize public fields as properties
———————————
maps are also supported
$map.firstKey, $map["firstKey"]
##both equivelent to map.get("firstKey");
#foreach ($e in $map)
the map.entry is $e
##will only print the value, no key rende#006699
#end
———————————
it will fail to assign null to a variable
#set ($o = $bean)
#set ($o = $nonExistingObject)
$o, $o.class
## still the bean, not null
#set ($o = $!nonExistingObject)
$o, $o.class
## still the bean, not empty string
#set ($o = "$!nonExistingObject")
$o, $o.class, $o.length()
## now it’s an empty string
———————————
investigating bool
b1: #if(true) Go, true! #end
##will print something
b2: #if(false) Go, false! #end
##will print nothing
b3: #if("true") Go, "true"! #end
## will print nothing.
b4: #if("false") Go, "false"! #end
## will print nothing. You can see "#if" doens’t take string literals
#set($theBool = false)
b5: #if($theBool) Go, "$theBool" #end
## will print nothing
b6: #if("$theBool") Go, "the bool" #end
##will print nothing since "#if" doens’t take string literals
#set($theBool = "false")
b7: #if($theBool) Go, "$theBool" #end
## will print something since $theBool is not null
b8: #if("abc" == "abc") abc #end
## For string comparison, "==" in VTL is equivlatent to .equals() in java
b9: #if($fakeObject) faked! #end
## wil print nothing since $fakeObject doesn’t exist
b10: #if($!fakeObject) faked! #end
## still prints nothing
b11: #if("$!fakeObject") faked! #end
## still prints nothing
———————————
variable scope: variables defined in loops
#foreach ($b in $beans)
#set($bi = $foreach.count)
#end
$!b
##will print nothing
$bi
##will print the last index; you can see variables defined by "#set" have global socpes
———————————
variable scope: variables defined inside \#if statements
#if (true)
#set($ifv = "definedInsideIf")
#end
$ifv
##will print something
———————————
variable scope: variables defined inside macros
#macro(inMacro)
#set($definedInsideMacro = "definedInsideMacro")
#end
$!definedInsideMacro
## will print nothing
#inMacro
$definedInsideMacro
## will print something
———————————
variable scope: reference global variables from macros
#macro(printGlobal)
hello print global: $bean.firstProperty, $bean.lastProperty
#end
#printGlobal
## will print something.
#macro(printGlobalWithParam $bean)
hello print global with param: $bean.firstProperty, $bean.lastProperty
#end
#printGlobalWithParam
## will print $bean’s properties
#printGlobalWithParam ($beans[2])
##now it will print beans[2]’s properties
———————————
macro’s pass-by: neither pass-by-ref or pass-by-value, but pass-by-name
#macro(doIt $a)
$a $a
#end
#set($bb = $beans[1])
#doIt ($bb.setFirstProperty("${bb.firstProperty} & postfix ") )
$bb.firstProperty
## will print "… & postfix & postfix" . The macro carries out "$bb.setFirstProperty("${bb.firstProperty} & postfix ")" for twice
———————————
does "=" mean reference assignment or value copy?
#set($bb = $beans[1])
$bb.setFirstProperty("newValue")
$bb.firstProperty
$beans[1].firstProperty
##will print "newValue"
———————————
\#define dosen’t take arguments
#set($b3 = $beans[3])
#define ($printBean)
hello $b3.firstProperty, hello $b3.lastProperty
#end
$printBean
##print properties of $b3
$printBean($beans[1])
## will not work
———————————
null value or undefined reference in non-strict reference mode
$emptyBean.firstProperty, $!emptyBean.firstProperty
$emptyBean.undefinedProperty, $!emptyBean.undefinedProperty
$emptyBean.firstProperty.length(), $!emptyBean.firstProperty.length()
———————————
notation: formal or informal ?
The size is $sizecm
##won’t work
The size is ${size}cm
##will work
The size is ${size}#if(1==2)km#{else}cm#end
##even a directive can be put as a formal notation