Velocity是一个基于Java的模板引擎。它允许任何人使用简单但功能强大的模板语言来引用Java代码中定义的对象。
当Velocity用于Web开发时,Web设计人员可以与Java程序员并行工作,根据模型 - 视图 - 控制器(MVC)模型开发Web站点,这意味着Web页面设计人员可以专注于创建看起来不错的站点,程序员可以专注于编写顶级代码。Velocity将Java代码与网页分离,使网站在其生命周期内更易于维护,并提供Java Server Pages(JSP)或PHP的可行替代方案。
Velocity的功能远远超出了网络领域; 例如,它可用于从模板生成SQL,PostScript和XML。它既可以用作生成源代码和报告的独立实用程序,也可以用作其他系统的集成组件。例如,Velocity为各种Web框架提供模板服务,使它们能够通过视图引擎根据真正的MVC模型促进Web应用程序的开发。
> 那么Velocity能做什么呢?假设你有一个根据一张模板表单、表格、页面、等等只需要更改一些变量,总体风格版面一致的需求,那么你就可以使用Velocity去进行模板变量赋值。
<!-- velocity代码生成使用模板 -->
<dependency>
<groupId>org.apache.velocity</groupId>
<artifactId>velocity</artifactId>
<version>1.7</version>
<exclusions>
<exclusion>
<groupId>commons-collections</groupId>
<artifactId>commons-collections</artifactId>
</exclusion>
</exclusions>
</dependency>
<!-- collections工具类 -->
<dependency>
<groupId>commons-collections</groupId>
<artifactId>commons-collections</artifactId>
<version>3.2.2</version>
</dependency>
在模板VTL中,有一些基本的规则,如下:
- 引用的前面是用$,表示获取或临时存储数据;
- 指令的前面是#,表示执行相关的操作;
- 模板中单独使用变量时,表示将变量的内容输出,如$a;
- \为转义字符,表示不将后序元素当变量,如\$a
- 变量无值时,如果希望空白显示,可使用$!a,即在$后加!
- 单行注释用## ,多行注释,用#* *#
- vtl中的变量标识符必须以字母开头
用于变量赋值,注意,双引号内的引用会被解析,单引号的引用不会被解析,如
`(1)#set( $a = 1 )`
`(2)#set( $list = ["a","b","c"] )`
`(3)#set( $a = "$b+$c" )`
`(4)#set( $a = '$b+$c' )`
条件判断语句,如
#if($a>1)
a>1
#elseif($a<1)
a<1
#end
循环指令,格式如 #foreach($ref1 in $ref2) [statement] #end ,如
#foreach ($t in $list) $t #end
例子:
#set( $list = ["pine", "oak", "maple"]) #foreach ($element in $list) This is $element. #end
输出的结果为:
1. This is pine.
2. This is oak.
3. This is maple.每次循环$list中的一个值都会赋给$element变量。
> $list可以是一个Vector、Hashtable或者Array。分配给$element的值是一个java对象,并且可以通过变量被引用。
提示:velocity中大小写敏感。
包含指令,导入本地文件,同时模板引擎并不处理导入文件的内容,可包含多个,中间用逗号分隔,如:
#include("one.gif“,”two.txt",$threefile)
解析指令,相对#include的,#parse可以对包含的文件,通过模板引擎进行解析,不过包含的文件只能有一个,不能多个。
如:#parse("a.vm")
停止指令,即停止模板引擎的执行,可用于程序调试,注意不用能在#if和#foreach中使用
宏指令,可用于定义代码段,宏内还可以带参数,
a)不带参数的宏,如
定义宏#macro(t) <span>yes</span> #end
使用宏
#foreach #t() #end
b)带参数的宏,如
定义宏#macro(t $p) <span>$p</span> #end
使用宏
#foreach #t("yse") #end
所有的VTL statement都是以`#`开头,且包含一个指示符,当客户访问你的页面时, the Velocity Templating Engine将搜索页面中的所有#符号,如果确定这是一个VTL声明时就按一定规则处理动态内容,符号`#`仅仅只是表明这可能是一个VTL声明.记住以下的规则:
使用`$`字符开始的引用用于得到什么;使用`#`字符开始的指令用于作些什么。在下面的例子中,一个值被分配给$foo变量,并在其后被引用。
#set ( $foo = “Velocity” ) JHsser $foo !
上面的实现结果是在页面上打印`“JHsser Velocity !”`
单行注释:##内容
多行注释:#* 内容 *#
文档格式:#** 内容 *#
- ${mudSlinger} 变量
- ${customer.Address} 属性
- ${purchase.getTotal()} 方法
如果写成如下的语法格式,当值为null的时候会原样输出字符串
- $mudSlinger 变量
- $customer.Address 属性
- $purchase.getTotal() 方法
所以尽量使用正式的标记或者可以写成如下的方式(添加!可以让值为null的时候不进行赋值):
- $!mudSlinger 变量
- $!customer.Address 属性
- $!purchase.getTotal() 方法
也可以一同使用
- $!{mudSlinger} 变量
- $!{customer.Address} 属性
- $!{purchase.getTotal()} 方法
拓展:
(1)`${name}` ,也可以写成:`$name`。提倡用前面的写法。
例如:你希望通过一个变量`$vice`来动态的组织一个字符串。Jack is a $vicemaniac
本来变量是`$vice`现在却变成了`$vicemaniac`,这样Veloctiy就不知道您到底要什么了。所以,应该使用规范的格式书写 :
Jack is a ${vice}maniac
现在Velocity知道变量是`$vice`而不是`$vicemaniac`。
注意:当引用属性的时候不能加`{}`。
(2)`$customer.address` 引用时,查找顺序是:
`1.getaddress() ——> 2. getAddress() ——> 3. get(“address”) ——> 4. isAddress()`
#foreach ($element in $list) ## inner foreach 内循环 #foreach ($element in $list) This is $element. $velocityCount <br>inner<br> #end ## inner foreach 内循环结束 ## outer foreach 外循环 This is $element. $velocityCount <br>outer<br> #end
语句中也可以嵌套其他的语句,如#if…#else…#end等。
Velocity 也具有逻辑AND、OR 和 NOT 操作符。如:
## example for AND #if($foo && $bar)<strong>This and that</strong> #end
例子中 `#if()` 指令仅在 `$foo` 和 `$bar` 都为真的时候才为真。如果 `$foo` 为假,则表达式也为假;并且 `$bar` 将不被求值。
如果 `$foo` 为真,Velocity 模板引擎将继续检查`$bar`的值,
如果 `$bar` 为真,则整个表达式为真。并且输出 `This AND that` 。
如果 `$bar` 为假,将没有输出因为整个表达式为假。
如果reference被定义,两个’\’意味着输出一个’\’,如果未被定义,刚按原样输出。如:
#set($email = "foo" ) $email \$emai \\$email \\\$email
输出:
- foo
- \foo
如果$email 未定义
$email \$email \\$email \\\$email
输出:
Velocity内置了一些对象,在vm模版里可以直接调用,列举如下:
`$request`、`$response`、`$session`,另外,模板内还可以使用`$msg`内的消息工
具访问 Struts 的国际化资源,达到简便实现国际化的方法。
对数组的访问在`Velocity`中存在问题,因为`Velocity`只能访问对象的方法,而数组又是一个特殊的`Array`,所以虽然数组可以进行循环列举,但却不能定位访问特定位置的元素,如`strs[2]`,数组对固定位置元素的访问调用了`Array`的反射方法`get(Object array, int index)`,而`Velocity`没能提供这样的访问,所以数组要么改成`List`等其他类容器的方式来包装,要么就通过公用`Util`类的方式来提供,传入数组对象和要访问的位置参数,从而达到返回所需值的目的。
直接进行四则运算将会默认为字符串连接,因此运算应该是如下的方式解决。
如果`$foo=2`.则`$foo + 1`结果是21,而不是3.
需要先`#set ( $value = $foo + 1 )` ,然后`$value`结果才是3
当Velocity应用在应用程序时,一般分一下几步:
`初始化Velocity ——> 创建context对象 ——> 添加数据到context ——> 选择模板 ——> 合并模板和数据,产生输出页面`
参考资料(进行布局组合,十分感谢两位博主的博客):