Spring Boot实战(1)——Velocity语法

来源:互联网 发布:九亿娱乐域名 编辑:程序博客网 时间:2024/06/05 02:11

主要是根据需要翻译了部分内容,具体查看官方文档点击打开链接

Velocity是一个基于Java的模板引擎。它允许网页设计人员参考Java代码中定义的方法。Web设计人员可以与Java程序员并行工作,根据模型 - 视图 - 控制器(MVC)模型开发网站,这意味着网页设计师可以专注于创建一个精心设计的网站,程序员可以专注于写一流的代码。Velocity将Java代码与Web页面分开,从而使Web站点在长期内更加可维护,并为Java Server Pages(JSP)或PHP提供了可行的替代方案。

Velocity可用于从模板生成网页,SQL,PostScript和其他输出。它可以用作生成源代码和报告的独立实用程序,也可以作为其他系统的集成组件使用。完成后,Velocity将为Turbine Web(一个基于servlet的框架)应用程序框架提供模板服务。Velocity + Turbine将提供一个模板服务,可以根据真正的MVC模型开发Web应用程序。

一、Velocity TemplateLanguage (VTL)

VTL使用引用将动态内容嵌入到网站中,变量是一种引用类型。变量是可以参考Java代码中定义的内容的一种引用类型,也可以从网页本身的VTL 语句中获取其值。

#set( $a = "Velocity" )

该VTL语句与所有VTL语句一样,以#字符开头,并包含一个指令:set。当在线访问者请求您的网页时,Velocity模板引擎将搜索网页以查找所有#个字符,然后确定VTL语句的开始标记以及与VTL无关的哪些#个字符。

该#字符后跟一个指令,set。该组指令使用的表达式(用括号括起来) -其分配的方程式值的变量。变量列在左侧,其值在右侧; 两个被一个=字符分开。

变量为$ a,值为Velocity。该变量与所有引用一样,以$字符开始。字符串值始终用引号括起来,单引号或双引号。单引号将确保引用的值将被分配给引用。双引号允许您使用Velocity引用和指令进行插值,例如“Hello $ name”,其中$ name将被替换为当前值,该字符串字面量分配给左侧的=。

参考以$开头,用于获取某些东西。指令以#开头,用于做某事。

二、语法

2.1、注释

单行注释:##单行注释内容

多行注释:

#*     多行注释内容*#

注释块:
#**   这是一个VTL注释块,  可用于存储  文档作者和版本  信息等信息:    @author John Doe     @version 5 *#

2.2 引用类型

VTL中有三种引用类型:变量,属性和方法。

2.2.1 变量

变量的简写符号由前导“$”字符,后跟VTL 标识符组成。VTL标识符必须以字母字符(a .. z或A .. Z)开头。其余字符仅限于以下类型的字符:

字母(a .. z,A .. Z)

数字(0 .. 9)

下划线(“_”)

2.2.2 属性

包括一个领先的$字符,后跟一个VTL标识符,后跟一个点字符(“.”)和另一个VTL标识符。

$customer.Address$purchase.Total

比如$customer.Address。它可以有两个含义。这可以意味着,查看标识为客户的哈希表,并返回与键地址相关联的值。但是$ customer.Address也可以指一个方法(参考方法的引用将在下一节讨论);$ customer.Address可以是一个写入$ customer.getAddress()的缩写方式。当页面被请求时,Velocity将确定这两种可能性中的哪一种是有意义的,然后返回适当的值。

2.2.3 方法

方法是由VTL标识符后跟VTL 方法体的前导“$”字符组成的引用。VTL方法体由VTL标识符,后跟左括号(“(”),后跟可选参数列表,后跟右括号(“)”)。

$customer.getAddress()$purchase.getTotal()$page.setTitle( "My Home Page" )$person.setAttributes( ["Strange", "Weird", "Excited"] )
2.2.4 属性查找规则

对于小写名称,例如$customer.address,序列是:

1、getaddress()

2、getAddress()

3、get("address")

4、isAddress()

对于大写属性名称,如$customer.Address:

1、getAddress()

2、getaddress()

3、get("Address")

4、isAddress()


2.3 渲染

将每个引用(无论是变量,属性还是方法)生成的最终值在呈现为最终输出时都将转换为String对象。如果有一个代表$foo的对象(如一个整数对象),那么Velocity将调用它的.toString()方法将该对象解析为一个String。

三、正式参考符号

将变量名用大括号包起来,使得正式的符号得到正确处理。

${mudSlinger}

${customer.Address}

${purchase.getTotal()}

四、安静参考符号

<input type =“text”name =“email”value =“ $ email ”/>

当表单最初加载时,变量引用$ email没有任何值,但是您更喜欢将空白的文本字段设置为值为“$ email”的文本字段。使用安静的参考符号避免了Velocity的正常行为; 而不是在VTL中使用$email,您将使用$!email。所以上面的例子如下所示:

<input type="text" name="email" value="$!email"/>

当初始加载表单并且$email仍然没有值时,将输出一个空字符串,而不是“$email”。

五、严格参考模式

引用需要被明确地放置到上下文中或者用#set指令定义,否则Velocity将抛出异常。在值为null的上下文中的引用不会产生异常。另外,如果尝试调用引用中没有定义指定方法或属性的对象的方法或属性,那么Velocity将抛出异常。如果尝试在空值上调用方法或属性,也是如此。

$bar被定义,但$foo没有被定义,所有这些语句都将抛出异常:

$foo                         ## Exception#set($bar = $foo)            ## Exception#if($foo == $bar)#end        ## Exception#foreach($item in $foo)#end  ## Exception

以下语句显示了尝试调用不存在的方法或属性时Velocity将抛出异常的示例。在这些例子中,$ bar包含一个定义一个返回一个字符串的属性“foo”的对象,“retnull”返回null。

$bar.bogus          ## $bar does not provide property bogus, Exception$bar.foo.bogus      ## $bar.foo does not provide property bogus, Exception$bar.retnull.bogus  ## cannot call a property on null, Exception

严格模式要求在#if指令中比较>,<,> =或<=。另外,#foreach的参数必须是可迭代的(此行为可以通过property Directive.foreach.skip.invalid的属性修改)。最后,未定义的宏引用也将在严格模式下抛出异常。

Velocity尝试呈现,但是当引用为null时将导致异常。在这种情况下,简单地不提供任何参考,引用之前可以是'$!' 而不是'$',类似于非严格模式。请记住,这不同于在上下文中不存在的引用,它将在尝试以严格模式呈现时始终抛出异常。例如,在$foo之下,上下文中的值为null。

this is $foo    ## throws an exception because $foo is nullthis is $!foo   ## renders to "this is " without an exceptionthis is $!bogus ## bogus is not in the context so throws an exception
六、案例替代

Velocity参考利用了一些Java原理

$foo$foo.getBar()## is the same as$foo.Bar$data.setUser("jon")## is the same as#set( $data.User = "jon" )$data.getRequest().getServerName()## is the same as$data.Request.ServerName## is the same as${data.Request.ServerName}

Velocity利用Java的内省和bean功能,将Context中的对象以及objects方法的引用名解析出来。可以在模板中几乎任何地方嵌入和评估引用。

以SunMicrosystems定义的Bean规范为基础的Velocity是区分大小写的; 但是,其开发人员尽可能地抓住并纠正用户错误。当方法getFoo()在模板中引用时$bar.foo,Velocity将首先尝试$getfoo。如果失败了,那么会尝试$getFoo。同样,当模板引用时$bar.Foo,Velocity会首先尝试$ getFoo(),然后尝试getfoo()。

注意:对模板中的实例变量的引用未解决。只有引用JavaBean getter / setter方法的属性等同于解析(即$foo.Name解析为Foo类的getName()实例方法,而不是Foo的公共Name实例变量)。

七、指令

指令总是以一个“#”开头。与引用一样,指令的名称可以由一个“{”和一个“}”符号括起来。这对于紧跟文本的指令很有用。使用括号与#else该行的其余部分分开。

#if($a==1)true enough#{else}no way!#end
7.1 设置

#SET指令用于设置的参考值。一个值可以分配给变量引用或属性引用,这在括号中发生

#set( $primate = "monkey" )#set( $customer.Behavior = $primate )

分配的左侧(LHS)必须是变量引用或属性引用。右侧(RHS)可以是以下类型之一:

1、变量参考

2、字符串字面量

3、属性参考

4、方法参考

5、数字字面值

6、ArrayList

7、map

#set( $monkey = $bill ) ## variable reference#set( $monkey.Friend = "monica" ) ## string literal#set( $monkey.Blame = $whitehouse.Leak ) ## property reference#set( $monkey.Plan = $spindoctor.weave($web) ) ## method reference#set( $monkey.Number = 123 ) ##number literal#set( $monkey.Say = ["Not", $my, "fault"] ) ## ArrayList#set( $monkey.Map = {"banana" : "good", "roast beef" : "bad"}) ## Map

注意:对于ArrayList示例,使用[..]操作符定义的元素可以使用ArrayList类中定义的方法访问。所以,例如,你可以使用$ monkey.Say.get(0)访问上面的第一个元素。

类似地,对于Map示例,可以使用Map类中定义的方法来访问{}运算符中定义的元素。所以,例如,你可以使用$ monkey.Map.get(“banana”)访问上面的第一个元素来返回一个String'good',或者甚至$ monkey.Map.banana来返回相同的值。

RHS也可以是一个简单的算术表达式

#set( $value = $foo + 1 )#set( $value = $bar - 1 )#set( $value = $foo * $bar )#set( $value = $foo / $bar )

如果RHS是评估为空的属性或方法引用,则不会将其分配给LHS。根据Velocity的配置方式,通常不可能通过这种机制从上下文中删除现有的引用。(注意,通过更改其中一个Velocity配置属性可以允许这一点)。

#set( $result = $query.criteria("name") )The result of the first query is $result#set( $result = $query.criteria("address") )The result of the second query is $result

如果$query.criteria(“name”)返回字符串“bill”,$ query.criteria(“address”)返回null,则上述VTL将呈现如下:

The result of the first query is billThe result of the second query is bill
7.2 文字

当使用#set指令时,将解析和呈现包含在双引号字符中的字符串文字,当字符串文字包含在单引号字符中时,将不会被解析。

7.3 条件 - If / ElseIf / Else
#if( $foo )  <strong>Velocity!</strong>#end

变量$ foo被评估以确定它是否为真,这将在下列情况之一发生:

1、$ foo是一个具有真实值的布尔值(true / false)

2、$ foo是一个字符串或集合,它不为空,不为空

3、$ foo是等于零的数字

4、$ foo是一个不为空的对象(字符串,数字或集合除外)

#if( $foo < 10 )    **Go North**#elseif( $foo == 10 )    **Go East**#elseif( $bar == 6 )    **Go South**#else    **Go West**#en
7.4 

关系和逻辑运算符

==只能用于测试对象的相等性

&&逻辑与

|| 逻辑or

! 逻辑NOT

7.5 循环 -Foreach循环
#foreach( $product in $allProducts )    <li>$product</li>#end
此#foreach循环将导致列表中所有产品(目标)的$ allProducts列表(对象)循环。每次循环中,$ allProducts的值都将放入$ product变量中。
$ allProducts变量的内容是Vector,Hashtable或Array。分配给$ product变量的值是Java对象,可以从变量引用。例如,如果$ product真的是Java中的Product类,则可以通过引用$ product.Name方法(即$ Product.getName())来检索其名称。
让我们说,$ allProducts是一个Hashtable。如果要检索Hashtable的键值以及Hashtable中的对象,可以使用如下代码:
#foreach( $key in $allProducts.keySet() )    Key: $key -> Value: $allProducts.get($key)#end

Velocity提供了一个简单的方法来获取循环计数器,以便您可以执行以下操作:

#foreach( $customer in $customerList )    $foreach.count $customer.Name#end

Velocity现在也提供了一个简单的方法来判断你是否在循环的最后一次迭代中:

#foreach( $customer in $customerList )    $customer.Name#if( $foreach.hasNext ),#end#end

7.6 包括

#include脚本元素允许模板设计者导入本地文件,然后将其插入到其中的位置的#include指令定义。该文件的内容不会通过模板引擎呈现。出于安全考虑,要包括的文件只能在TEMPLATE_ROOT下。
#include指令引用的文件用引号括起来。如果包含多个文件,则应以逗号分隔。

#include(“one.gif”,“two.txt”,“three.htm”)
7.7 解析

#parse脚本元素允许模板设计者导入包含VTL的本地文件。Velocity将解析VTL并渲染指定的模板。

八、Velocity宏

源文档内容太多,借用叶大神的例子,文档里的解释。

#macro脚本元素允许模板设计者定义VTL模板的重复段。Velocimacros在广泛的场景中非常有用,既简单又复杂。Velocimacro是为了节省击键和最小化排版错误而创建的,它介绍了Velocimacros的概念。

#macro (render_color, $index, $color)    Color Render Macro $index, $color#end
在本示例中定义的Velocimacro是render_color,它可以以类似于任何其他VTL伪指令的方式被调用:

#render_color ()
当调用此模板时,Velocity将用包含单个空数据单元格的行替换# render_color()。如果我们想在该单元格中放置某些东西,我们可以改变宏以允许一个主体:

#foreach($color in $colors)        #render_color($foreach.index, $color)#end

最终结果:

Color Render Macro 0, REDColor Render Macro 1, GREENColor Render Macro 2, BLUE