zoukankan      html  css  js  c++  java
  • velocity 继续之 语法学习篇

    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是做什么的,这是什么,它存在的意义到底是什么,这个还对其进一步的学习...

  • 相关阅读:
    如何在软件频繁改变时测试?归纳总结
    PE文件格式资源
    PE文件格式重定位
    PEB模块链表Ldr
    PE文件格式导入表和IAT
    PE文件格式导出表
    win32汇编问题指令
    win32汇编问题堆栈
    硬盘基本知识
    SEH异常处理
  • 原文地址:https://www.cnblogs.com/laizhd/p/2143518.html
Copyright © 2011-2022 走看看