1.变量
在变量的定义中,我们用#set指令.比如#set($name="laizhd")
如果只写#set($name)或#set($name = null)会抛出org.apache.velocity.runtime.parser.ParseException异常
如果在双引号中的字符串字面量中出现了变量的名称,该变量名称将被解析,比如#set($fullname = "lai-$name"),将对字符串里的$name进行解析,最后$fullname的值是"lai-laizhd".
当然,从$name = "laizhd" 中,我们可以得知velocity中的变量是弱类型的,因为我们并不需要特别指明$name是字符串类型.如果我们要给一个变量赋值整形,可以直接给数字的字面量,而不用加以引号,比如#set($num = 123).
还有,因为是弱类型,所以在#set($name = 'laizhd'")之后,我又加了一句#set($name = 123)是不后报错的,而且后面的值会都以$name = 123 为准进行引用.
另外,在赋值表达式的右边,其类型除了有字符串,整型以外,还可以有变量引用,如$name = $num;可以用属性引用,如$people.ID = $Student.ID;可以用方法引用,如$people.ID = $student.getID($name);还可以是数组列表,如$string.list = ["a","b","c"]
刚刚把所有的情况都实验了一遍,其它的都还很好理解,但对于属性和方法这一块,需要做一个探究.
属性只能是来自于java中所定义的属性,而且要知道,在模版中调用一个属性的引用,在实际上它还是把这个属性当前一个方法来调用.
比如调用$student.Name并不是说在Student对象中真的有一个Name成员,而是模版调用了Student的getName()方法,所以它$student.Name其实是$student.getName()方法调用的一个简写.
我实验用的Temple代码如下:
#set($boy = "lai")
Hello $name! Welcome to $site world!
$boy and the $girl
##字符串赋值
#set($test = "test")
stirng = $test
##数值赋值
#set($test = 123)
number = $test
##变量引用赋值
#set($test = $boy)
test = $test
##属性引用
#set($student = $stu)
id = $stu.ID;
id = $student.ID
##方法引用
#set($info = $stu.toString("lai"))
info = $info
##数组引用
#set($list = ["a",123,"b",$stu,$stu.ID,$stu.Name])
#foreach ($element in $list)
This is $element.
#end
实验用的java代码如下:
import java.io.StringWriter;
import org.apache.velocity.app.VelocityEngine;
import org.apache.velocity.Template;
import org.apache.velocity.VelocityContext;
public class VelocityTest {
public static void main(String[] args) throws Exception {
/* first, get and initialize an engine */
VelocityEngine ve = new VelocityEngine();
ve.init();
/* next, get the Template */
Template t = ve.getTemplate("hello.vm");
VelocityContext context = new VelocityContext();
context.put("name", "紫蝶_妖儿");
context.put("site", "http://ctfzh.cnblogs.com");
Student stu = new Student(23,"lai");
context.put("stu", stu);
/* now render the template into a StringWriter */
StringWriter writer = new StringWriter();
t.merge(context, writer);
System.out.println(writer.toString());
/* create a context and add data */
/* show the World */
}
}
public class Student {
public int ID;
public String Name;
public Student(int id,String name) {
ID = id;
Name = name;
}
public int getID()
{
return ID;
}
public String getName()
{
return Name;
}
public String toString(String str)
{
return str + ID + Name;
}
}
2.循环.
在上面的例子中已经有出现过,主要是通过#foreach指令来完成.我们要用来遍历的变量可以对应于java中Vector,Hashtable,或者Array
在Velocity中,还提供了一种特别的循环方式:
#set($bar = [0..3]); ##表示是的bar是个从0到3的数组
#set($bar = [2..-2]); ##表示的是bar是个从2到时-2的数组
另外有一个预定义的变量$velocityCount,自动记录循环次数.
3.嵌套
velocityCount支持嵌套,比如循环嵌套
4.条件语句,#if,#elseif,#else.
5.注释
##相当于代码里的//
#* *# 相当于代码里的/* */
6.关系逻辑操作符
有AND,OR,NOT操作符
7.宏
velocity支持宏定义,不过在这里我们可以把它当前是一种函数来使用.
对宏定义的格式:
#macro(宏的名称 $参数1 $参数2 ...)
语句体
#end
对宏的调用:
#宏的名称($参数1 $参数2 ...)
实验代码:
#macro(mac $a $b)
$a loves $b ;
#end
#mac("lai" "tong")
这里有个要特别注意的地方,就是参数之间用空格来分开,而不是平时所习惯的逗号
8.#stop指令
这个指令表示停止执行模板并返回,可以用于帮助debug
9.#include 与 #parse
#include是把一个文件包含进来,但模板引擎不会对文件里的内容进行解析渲染.
#include一次可以包含多个文件,文件名间使用逗号间隔,使用例子如下:
#include("one.gif","included.vm")
在对当前文件进行解析时候,如果遇到include就会把#include所指定的文件的内容给直接copy进来.
#parse一次只能包含一个文件,模版引擎会对parse进来的文件内容进行velocity语法上的解析渲染.
可以复用#parse进行递归调用,在递归调用的过程中,于外部声明的变量可以被内部所调用,同时如果内外层出现同名的变量名里,内部变量会覆盖外部变量.
10.转义字符
如果引用变量已经被定义,如$boy已经被定义,且值为"lai",则\$boy会输出lai.
如果$boy未被定义,则会直接输出\$boy.
其它场合转义字符的用法与java中相似.
11.内置对象.
对于vm中的内置对象,这可能要进一步深入的学习才知道怎么使用了,至少目前还是不懂的,毕竟我才接触了两天.
12.数组
因为velocity归根只能访问对象的方法,而数组又就一个特殊的Array,在对固定位置元素的访问的时候调用了Array的get(Object array,int index)方法,但velocity没办法提供这样的访问,所以要么对数组进行其它方式的包装,要么就通过公用Util类的方式来提供(这句话我不是很明白),传入数组对象和要访问的位置参数,从而达到返回所需值的目的.
这么用大概是知道了,不过具体velocity是做什么的,这是什么,它存在的意义到底是什么,这个还对其进一步的学习...