精华内容
下载资源
问答
  • 1.简介Velocity是一款基于Java的模板引擎。它允许Web页面设计者引用Java代码中定义的方法。Web设计者能与根据Model-View-Controller (MVC)模型开发Web网站的Java程序员合作,意味着Web页面设计者能将注意力放在创建...

    1.简介

    Velocity是一款基于Java的模板引擎。它允许Web页面设计者引用Java代码中定义的方法。Web设计者能与根据Model-View-Controller (MVC)模型开发Web网站的Java程序员合作,意味着Web页面设计者能将注意力放在创建设计精良的网站,而程序员能将注意力放在编写代码上。Velocity从Web页面中分离Java代码,使Web网站在长时间运行时更可维护性和提供Java Server Pages(JSP)或PHP的替代方案。

    Velocity能用于从模板产生Web页面、SQL、PostScript和其它输出。它能用于作为单独的工具类生成源码和报表,或作为其它系统的一个整合组件。Velocity将为Turbine Web应用程序框架提供模板服务。Velocity+Turbine将提供模板服务允许Web应用程序根据真实MVC模型开发。

    2.安装

    • JDK(必须)

    • Jakarta Commons Collections(必须)

    • Jakarta Commons Lang(必须)

    • Excalibur(ex-Avalon)Logkit(可选,如果使用默认的基于文件的日志时需要)

    • Jakarta ORO(可选,当使用org.apache.velocity.convert.WebMacro模板转换工具或org.apache.velocity.app.event.implement.Escape Reference ReferenceInsertionEventHandler时使用)

    3.实践

    3.1 基本步骤

    • 初始化Velocity

    • 创建Context对象

    • 添加数据对象到Context

    • 选择模板

    • “合并”模板和数据产生输出

    3.2 单例

    模板:

    bfab997c5308a9c5c85e6c6327a532c6.png

    代码:

    Velocity.init();VelocityContext context = new VelocityContext();context.put( "word", "Hello Velocity!");// 模板路径默认是当前项目的根目录Template template = Velocity.getTemplate("src/main/java/com/study/velocity/HelloWord.vm");StringWriter sw = new StringWriter();template.merge(context, sw);System.out.println(sw);

    3.3 多例

    与单例不同,多例可以在用一个JVM或Web应用程序中维护多组配置。

    VelocityEngine ve = new VelocityEngine();ve.init();Template t = ve.getTemplate("src/main/java/com/study/velocity/HelloWord.vm");StringWriter sw = new StringWriter();VelocityContext context = new VelocityContext();context.put( "word", "Hello Velocity!");t.merge(context, sw);System.out.println(sw);

    4.注释

    注释一向是一门编程语言的必须成员,没有注释的代码不能称之为好代码。注释允许放

    置描述文本在模板引擎中。注释通常用于提示自己和解释别人VTL(VelocityTemplate Language)语句在做什么。

    Velocity包含三种注释:

    • 单行注释

    • 多行注释

    • 文档注释

    4.1 单行注释

    单行注释以 ## 开始,从被注释的位置开始到行结尾的所有字符将不被模板引擎解析。

    ## 这是单行注释

    4.2 多行注释

    以 #* 开始,*#结尾,中间的内容不被模板引擎解析。

    #* 这是多行注释*#

    4.3 文档注释

    类似于JavaDoc注释,用于存储各种额外信息。

    #**这是文档注释@author  赵凡@version  1.0*#

    5.引用

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

    5.1 变量

    变量的速记符号由前导“$”字符后随VTL标识符组成。VTL标识符必须以字母开头,合法字符包含:

    • 字母

    • 数值

    • 连字符

    • 下划线

    下面是VTL中有效的变量引用:

    $foo$mudSlinger$mud-slinger$mud_slinger$mudSlinger1

    当VTL引用一个变量时,例如$foo,变量能从模板中的set指令或Java代码中的Context获取值。

    #set( $word = "Hello Velocity!" )${word}
    5.2 属性

    代码:

    Velocity.init();VelocityContext context = new VelocityContext();User user = new User();user.setUsername("xxxx");context.put( "user", user);Template template = Velocity.getTemplate("src/main/java/com/study/velocity/Properties.vm");StringWriter sw = new StringWriter();template.merge(context, sw);System.out.println(sw);public class User {    private String username;    public String getUsername() {        System.out.println("do get");        return username;    }    public void setUsername(String username) {        this.username = username;    }}
    板:
    $user.username
    输出结果:
    do getxxxx
    由上面的结果表明,$user.username调用的就是user的getUsername方法。

    5.3 方法

    方法引用由前导“$”字符后随VTL标识符和VTL方法体。VTL方法体由VTL标识符后随左圆括号、可选参数列表、右圆括号。下面是有效的VTL:

    $sun.getPlanets()$annelid.getDirt()$album.getPhoto()$sun.getPlanet( ["Earth", "Mars", "Neptune"] )$sisyphus.pushRock()$book.setTitle( "Homage to Catalonia" )
    5.4 属性查找规则

    就像前面所说的,属性通常引用父对象的方法。Velocity很聪明,计算请求属性的方法。它基于命名规则查找方法。期望的查找序列依赖于是否属性名开始与大写字母。对于小写字母,例如$customer.address的顺序是:

    getaddress()getAddress()get("address")isAddress()
    对于大写字母稍有不同:
    getAddress()getaddress()get("Address")isAddress()
    5.5 渲染

    每个引用(无论变量、属性或方法)最后产生的值转换为字符串对象。如果一个对象是Integer,那么Velocity将调用它的.toString()方法解析对象为字符串。

    5.6 下标表示法

    使用下标形式$foo[0]能用于访问指定索引的对象。这种形式的同义词在指定对象上调用get(Object)方法上一致,例如$foo.get(0)

    $foo[0]       ## $foo takes in an Integer look up$foo[$i]      ## Using another reference as the index$foo["bar"]   ## Passing a string where $foo may be a Map

    括号语法也适用于Java数组,因为Velocity包装数组在访问对象中,提供get(Integer)

    方法返回指定元素。

    括号语法在任何适用.get的地方都是有效的,例如:

    $foo.bar[1].junk$foo.callMethod()[1]$foo["apple"][4]
    引用也可以使用索引设置,例如:
    #set($foo[0] = 1)#set($foo.bar[1] = 3)#set($map["apple"] = "orange")
    5.7 正规引用符号

    上面的引用符号都是缩写,正式的引用符号如下所示:

    ${mudSlinger}${customer.Address}${purchase.getTotal()}
    大多数情况下,可以使用缩写,但是在一种情况下,必须使用正式写法。
    Jack is a $vicemaniac.

    上面的例子中,变量是vicemaniac,但是我们实际想要的是vice,此时,我们可以在变

    量前后加上中括号来表示这个变量。

    Jack is a ${vice}maniac.
    5.8 处理未定义引用

    当Velocity遇到了未定义的引用时,默认会原样输出引用。可以使用以下方式使其输出

    空串。

    $!email$!{email}

    Velocity 1.6引入严格引用模式的概率,通过设置Velocity配置属性

    "runtime.references.strict”为true激活。在未定义或歧义的情况下,Velocity将抛出异常。使用该设置引用必须明确放置在context中或使用#set指令定义或抛异常。

    引用在context中有一个null值将不会产生一个异常。此外,如果试图调用不存在的方

    法或属性将抛出异常。如果试图调用的对象是null抛出异常。

    在下面的例子中,$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没有bogus属性,Exception$bar.foo.bogus      ## $bar.foo没有bogus属性,Exception$bar.retnull.bogus  ## 不能在null上调用属性,Exception
    #if和#elseif指令中的引用比较特殊:
    #if ($foo)#end                  ## False#if ( ! $foo)#end               ## True#if ($foo && $foo.bar)#end      ## False并且$foo.bar将不会计算#if ($foo && $foo == "bar")#end ## False并且$foo == "bar"将不会计算#if ($foo1 || $foo2)#end        ## False $foo1并且$foo2将不会计算

    严格模式必须在#if指令中包含>、=或<=。同时,参数#foreach必须迭代(该行

    为能修改属性 directive.foreach.skip.invalid)。最后,在严格模式下,未定义宏引用

    也将抛出异常。

    this is $foo    ## 抛出异常,因为$foo是nullthis is $!foo   ## 渲染为"this is "没有异常this is $!bogus ## bogus不在context中,因此抛出异常

    6.指令

    指令允许模板设计者生成Web网站的动态内容,而指令——易于使用脚本元素能用于创建操作Java代码输出——允许Web设计者真正负责Web网站的外观和内容。

    指令总是以#开始。如同引用,指令的名字可以通过{和}符号括起来。通常文本紧随其后。例如以下产生错误:

    #if($a==1)true enough#elseno way!#end
    在这种情况下,使用花括号分隔#else。
    #if($a==1)true enough#{else}no way!#end
    6.1 #set

    #set指令用于设置引用的值。值能复制给变量引用或属性引用,这发生在括号中:

    #set( $primate = "monkey" )#set( $customer.Behavior = $primate )
    等于号左边必须是一个变量引用或属性引用。右边可以是以下类型:
    • 变量引用

    • 字符串字面值

    • 属性引用

    • 方法引用

    • 数值字面值

    • ArrayList

    • Map

    #set( $monkey = $bill ) ## variable reference#set( $monkey.Friend = "monica" ) ## string literal#set( $monkey.Blame = $whitehouse.Leak ) ## property reference#set( $monkey.Plan = $spindoctor.weave($w#set( $monkey = $bill ) ## variable reference#set( $eb) ) ## 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")访问第一个元素返回一个字符串"good",或$monkey.Map.banana返回相同值。等号右边也可以是简单的算术表达式:

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

    如果右边是计算为null的属性或方法引用,它将不赋值给左边。依赖于Velocity的配置,通常这种机制不能够删除已存在的引用。

    #set( $result = $query.criteria("name") )第一个查询的结果是$result#set( $result = $query.criteria("address") )第二个查询的结果是$result

    如果$query.criteria("name")返回字符串“bill”,而$query.criteria("address")返回null,上面VTL将渲染为:

    第一个查询的结果是bill第二个查询的结果是bill
    6.2 字面值

    当使用#set指令时,封闭在双引号里面的字符串字面值将被解析和渲染:

    #set( $directoryRoot = "www" )#set( $templateName = "index.vm" )#set( $template = "$directoryRoot/$templateName" )$template
    输出:
    www/index.vm
    然而,当字符串字面值封装在单引号中时,它将不被解析:
    #set( $foo = "bar" )$foo#set( $blargh = '$foo' )$blargh
    渲染为:
    bar$foo

    默认,这种在Velocity中使用单引号渲染未解析的文本是有效的。该默认能通过velocity.properties编辑,例如stringliterals.interpolate=false。#[[不解析我!]]#语法允许模板设计者易于在VTL代码中使用大块的不解释和不解析内容。

    #[[#foreach ($woogie in $boogie)  nothing will happen to $woogie#end]]#
    渲染为:
    #foreach ($woogie in $boogie)  nothing will happen to $woogie#end

    7.条件指令

    7.1 if/elseif/else

    在Velocity中,#if指令允许在if语句条件为true时包括文本。例如:

    #if( $foo )   Velocity!#end
    变量$foo计算决定是否为true,这三种情况下将发生什么:
    • $foo是boolean(true/false),为true

    • $foo是字符串或集合,不为null和不为空

    • $foo是一个不为null的对象(除了字符串或集合)

    记住,Velocity context只包含Object,因此,当我们说"boolean",它将表示为Boolean(类)。

    如果条件为true,#if和#end语句之间的内容变成输出。在这种情况下,如果$foo是true,输出将是:“Velocity!”。相反的,如果$foo有一个null值,或者有一个boolean false,条件为false,那么没有输出。

    #elseif或#else语句能与#if语句连用。注意,Velocity模板引擎将在第一个条件表达式为true的语句终止。在以下例子中,假设$foo为15,$bar为6.

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

    在该例子中,$foo大于10,因此前面两个比较失败。接下来$bar与6比较为true,因此输出时Go South。

    7.2 关系和逻辑运算符

    Velocity使用等价运算符决定变量之间的关系。下面是一个简单的例子来说明如何使用等价运算符。

    #set ($foo = "deoxyribonucleic acid")#set ($bar = "ribonucleic acid")#if ($foo == $bar)  In this case it's clear they aren't equivalent. So...#else  They are not equivalent and this will be the output.#end

    注意,==的语义与Java中的略有不同,只能用于测试对象是否相等。在Velocity中,

    等价运算符能直接用于比较数值、字符串或对象。当对象是不同的类时,通过调用每

    个对象的toString()获取字符串表现形式然后比较。

    Velocity也有逻辑AND、OR和NOT运算符。下面例子演示,使用逻辑AND、OR和NOT运算符。

    ## 逻辑AND#if( $foo && $bar )    This AND that#end## 逻辑OR#if( $foo || $bar )    This OR That#end##逻辑NOT#if( !$foo )  NOT that#end

    这些逻辑运算符与Java中的逻辑运算符一致,此处不再累述。需要注意的是$!foo不会

    应为foo为null而报错。逻辑运算符也有自己的文本形式的版本:eq、ne、and、or

    not、gt、ge、lt和le。

    8.循环指令

    Velocity模板支持各种集合类型的迭代。

    • Object[] Velocity包装数据对象到迭代对象中,可以将其当做固定长度的List,可调用size()、isEmpty()和get(int)。

    • java.util.Collection Velocity将使用iterator()方法获取一个Iterator用于循环,因此,如果你实现了Collection接口,请确保iterator()返回一个Iterator。

    • java.util.Map Velocity依赖接口的values()方法获取一个Collection接口,调用iterator()方法检索Iterator用于循环。

    • java.util.Iterator、java.util.Enumeration 只是暂时支持。

    • 任意不返回null的public Iterator iterator()方法。

    8.1 Map

    迭代Map中的Key,通过Key获取Map中的元素,来带到迭代的功能。

    #foreach( $key in $allProducts.keySet() )    Key: $key -> Value: $allProducts.get($key)#end

    8.2 集合

    Velocity可以通过简单的方式获取循环中的计数器。

    <table>#foreach( $customer in $customerList )    <tr><td>$foreach.counttd><td>$customer.Nametd>tr>#endtable>

    Velocity也可以通过简单的方式告诉你,是否是最后一次循环。

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

    如果你想要#foreach循环一个基于0的索引,你能使用$foreach.index替$foreach.count。同样,提供$foreach.first和$foreach.last。如果你想要访问外部循环的#foreach循环的属性,你能直接通过$foreach.parent或$foreach.topmost属性引用它们(例如,$foreach.parent.index或$foreach.topmost.hasNext)。可以设置循环允许执行的最大次数。默认没有最大值(表示为0或更小),但这能在velocity.properties文件中设置为任意数值。

    directive.foreach.maxloops = -1

    如果你想要终止foreach,你现在能使用#break指令终止循环。

    ## list first 5 customers only#foreach( $customer in $customerList )    #if( $foreach.count > 5 )        #break    #end    $customer.Name#end
    9 导入外部文Velocity有两种方式从外部引入文件:包括和解析。

    9.1 包括

    #include脚本元素允许模板设计者导入本地文件,然后插入到#include指令定义的位置。文件的内容通过模板引擎渲染。由于安全原因,文件只能包含在TEMPLATE_ROOT。

    #include("one.txt")

    #include指令引用的文件被封闭在双引号中。如果多个文件被include,应该通过逗号分隔。

    #include("one.gif","two.txt","three.htm")
    可以使用变量替换文件名作为参数。
    #include("greetings.txt", $seasonalstock)
    9.2 解析

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

    模板。

    #parse("me.vm")

    像#include指令一样,#parse可以传入一个变量而不是模板。任意引用的模板必须在TEMPLATE_ROOT中。和#include指令不同,#parse只需要一个参数。VTL模板可以在模板中递归使用#parse引用。velocity.properties中的directive.parse.max.depth属性允许用户自定义最大递归数,默认设置为10。

    (如果velocity.properties文件中没有出现directive.parse.max.depth,Velocity将默认设置为10)。

    Count down.#set( $count = 8 )#parse( "parsefoo.vm" )All done with dofoo.vm!
    引用的模板:
    $count#set( $count = $count - 1 )#if( $count > 0 )    #parse( "parsefoo.vm" )#else    All done with parsefoo.vm!#end

    10.宏调用

    #macro脚本元素允许模板设计者定义重复的VTL模板片段。宏调用在简单和复杂的场

    景中非常广泛。

    定义宏:

    #macro( d )#end
    调用宏:
    #d()
    定义有体的宏,$!bodyContent为宏体:
    #macro( d )<tr><td>$!bodyContenttd>tr>#end
    调用有体的宏:
    #@d()Hello!#end
    义带参数的宏:
    #macro( tablerows $color $somelist )#foreach( $something in $somelist )    $something#end#end
    调用带参数的宏:
    #set( $greatlakes = ["Superior","Michigan","Huron","Erie","Ontario"] )#set( $color = "blue" )
    #tablerows( $color $greatlakes )
    展开全文
  • 我要在前台页面展示的数据是后台java对象中一个引用类型属性中的普通属性:如要展示order对象下的orderConsumer下的orderID,该怎么写呢?
  • 常用方法:$myarray.isEmpty()数组是否为空$myarray.size()获取数组元素... 访问Velocity 访问数组对象,无法通过类似 arr[2] 来访问特定位置的元素。#set($arr = [0, 1, 2, 3])$arr.get(2)注:Velocity 中的数组对...

    常用方法:

    $myarray.isEmpty()数组是否为空

    $myarray.size()获取数组元素个数

    $myarray.get(2)获取数组指定下标的元素

    $myarray.add()增加元素

    数组 & 访问

    Velocity 访问数组对象,无法通过类似 arr[2] 来访问特定位置的元素。

    #set($arr = [0, 1, 2, 3])

    $arr.get(2)

    注:Velocity 中的数组对应 Java 中的 List 对象。对于 Java 原生 Array 对象, 只能够 #foreach 进行遍历,无法使用 $arr[0] 和 $arr.get(0) 方法。

    范围(range)

    #foreach($item in [10..20])

    $item

    #end

    对象 & 访问

    #set($obj = {“key”:”value”, “name”:”space”})

    $obj.get(“key”)

    #foreach(#item in $obj)

    $item

    #end

    上面的 $item 取到的是 values,如果需要在遍历对象过程中,同时取到对象的 keys, 可以使用 entrySet() 或 keySet() 方法。

    #foreach($item in $!obj.entrySet())

    $!item.key : $!item.value

    #end

    #foreach($item in $obj.keySet())

    $item : $obj.get($item)

    #end

    注: 这种集合的遍历是无序的,即遍历顺序可能不同于 $obj 中元素的定义顺序 (据目前所知,是根据键的字母排序的)。

    另外有两种不完美解决方法:

    I:

    #set($obj = [

    {“key”:”key”, “value”:”value”},

    {“key”:”name”, “value”:”space”}

    ])

    #foreach($item in $obj)

    $item.key : $item.value

    #end

    II:

    #set($obj = [

    [“key”,”value”],

    [“name”,”space”]

    ])

    #foreach($item in $obj)

    $item.get(0) : $item.get(1)

    #end

    之所以说 不完美 是因为:对于已知的 key,本可以直接

    $obj.get(“key”)

    现在只能遍历并进行比较取得,而且较早的 Velocity 版本无法使用 #break, 以便在找到匹配项之后立即退出循环。

    #foreach($item in $obj)

    #if(“key” == $!obj.get(0))

    #set($myKey = $!type.get(1))

    ##break

    #end

    #end

    更多资料内容可参看:

    http://wiki.hotoo.me/Velocity-Notes.html

    http://wiki.hotoo.me/Velocity.html

    展开全文
  • velocity

    2017-09-11 22:50:49
    velocity,是一个基于Java的模板引擎,它允许任何人仅仅简单的使用模板语言来引用由java代码定义的对象。 当Velocity应用于web开发时,界面设计人员可以和java程序开发人员同步开发一个遵循MVC架构的web站点。这是很...

    velocity,是一个基于Java的模板引擎,它允许任何人仅仅简单的使用模板语言来引用由java代码定义的对象。 当Velocity应用于web开发时,界面设计人员可以和java程序开发人员同步开发一个遵循MVC架构的web站点。这是很好的一个地方,可以提高很多效率。下面来说下velocity的语法吧。

    1.获取:

    $!(var):如果有值则输出,如果为空,则不显示;
    
    ${var}:如果有值则输出,如果不存在,则将该代码原样输出;

    2.设置:

    #set{$var=5}:设置var的值为5
    1. 判断:
    #if{! $var}判断var为空
    
    #elseif{$var}判断var不为空
    
    #else{}
    #end

    4.循环:

    循环数组或List时:

    #foreach($var in list)
    
    ##输出当前迭代的次数
    
    $velocityCount
    
    ${var}
    
    #end

    5.判断是否为null

    1)使用 #ifnull() 或 #ifnotnull() 
       #ifnull ($foo) 
       要使用这个特性必须在velocity.properties文件中加入: 
    userdirective = org.apache.velocity.tools.generic.directive.Ifnull 
    userdirective = org.apache.velocity.tools.generic.directive.Ifnotnull 
    2) 使用null工具判断 
       #if($null.isNull($foo)) 

    ${}过滤输出
    输出表达式的计算结果,并进行过滤,比如:过滤变量中的HTML标签。

    示例:
    ${user.name}

    注:HTTL缺省开启了EscapeXmlFilter,以防止HTML注入攻击,参见:安全示例。如果你需要更强的过滤,请自行实现Filter,并配置到value.filters。此处为运行时热点,请注意性能。

    如果输出变量的类型为Template,则缺省不过滤,比如:${include(“foo.httl”)}

    $!{}不过滤输出
    原样输出表达式的计算结果,不进行任何过滤,通常用于输出HTML片段。

    示例:
    $!{body}

    展开全文
  • velocity详解

    2017-10-19 17:56:48
    velocity详解 模板引擎解析 看后必懂 Velocity是一个基于Java的模板引擎,通过特定的语法,Velocity可以获取java语言中定义的对象,从而实现界面和java代码的真正分离。
  • Velocity教程

    2020-09-30 10:29:48
    Velocity是一个基于Java的模板引擎,通过特定的语法,Velocity可以获取java语言中定义的对象,从而实现界面和java代码的真正分离,这意味着可以使用velocity替代jsp的开发模式了(实际上笔者所在的公司已经这么做了...

    Velocity是一个基于Java的模板引擎,通过特定的语法,Velocity可以获取在java语言中定义的对象,从而实现界面和java代码的真正分离,这意味着可以使用velocity替代jsp的开发模式了(实际上笔者所在的公司已经这么做了)。这使得前端开发人员可以和 Java 程序开发人员同步开发一个遵循 MVC 架构的 web 站点,在实际应用中,velocity还可以应用于很多其他的场景.

    1. Velocity的介绍

    Velocity是一个基于Java的模板引擎,其提供了一个Context容器,在java代码里面我们可以往容器中存值,然后在vm文件中使用特定的语法获取,这是velocity基本的用法,其与jsp、freemarker并称为三大视图展现技术,相对于jsp而言,velocity对前后端的分离更加彻底:在vm文件中不允许出现java代码,而jsp文件中却可以.

    作为一个模块引擎,除了作为前后端分离的MVC展现层,Velocity还有一些其他用途,比如源代码生成、自动email和转换xml等,具体的用法可以参考这篇文章.

    2. Velocty的基本用法

    在这里我们以一个HelloVelocity作为Velocity的入门实例.首先在官网下载velocity的最新发布包,新建普通java项目,引入其中的velocity-1.7.jar和lib文件夹下的所有jar包即可. 然后分为如下两步:

    2.1 初始化Velocity引擎

    编写HelloVelocity.java文件如下:

    public static void main(String[] args) {
        // 初始化模板引擎
        VelocityEngine ve = new VelocityEngine();
        ve.setProperty(RuntimeConstants.RESOURCE_LOADER, "classpath");
        ve.setProperty("classpath.resource.loader.class", ClasspathResourceLoader.class.getName());
        ve.init();
        // 获取模板文件
        Template t = ve.getTemplate("hellovelocity.vm");
        // 设置变量
        VelocityContext ctx = new VelocityContext();
        ctx.put("name", "Velocity");
        List list = new ArrayList();
        list.add("1");
        list.add("2");
        ctx.put("list", list);
        // 输出
        StringWriter sw = new StringWriter();
        t.merge(ctx,sw);
        System.out.println(sw.toString());
    }
    

    首先,我们在代码中初始化了VelocityEngine这个模板引擎,对其设置参数进行初始化,指定使用ClasspathResourceLoader来加载vm文件。然后我们就可以往VelocityContext这个Velocity容器中存放对象了,在vm文件中我们可以取出这些变量,从而进行模板输出.

    2.2 编写hellovelocity.vm文件

    其中,vm文件放在classpath目录下即可,类加载器会进行加载
    hellovelocity.vm文件如下:

    #set($greet = 'hello')
    $greet $name 
    #foreach($i in $list)
    $i
    #end
    

    控制台输出如下:

    hello Velocity
    1
    2
    

    2.3 Velocity的基本语法

    本文中只简单的介绍几个Velocity的基本语法,具体可以参考这篇文章这篇文章

    3.基础概念

    3.1 变量

    在Velocity中也有变量的概念,使用()使符声明变量,可以声明变量也可以对变量进行赋值(变量是弱类型的)。另外还可以使用取出在VelocityContext容器中存放的值

    #set(${!name} = "velocity")
    #set(${!foo} = $bar)
    #set($foo =“hello”)
    #set($foo.name = $bar.name)
    #set($foo.name = $bar.getName($arg))
    #set($foo = 123)
    #set($foo = [“foo”,$bar])
    

    需要注意,上面代码中 !使!{}的写法,使用vari获取变量时,如果变量不存在,Velocity引擎会将其原样输出,通过使用$!{}的形式可以将不存在的变量变成空白输出.

    3.2 循环

    在Velocity中可以使用循环语法遍历集合,语法结构如下:

    #foreach($item in $list)
     $item
     $velocityCount 
    #end
    

    其中,$item代表遍历的每一项,velocityCount是Velocity提供的用来记录当前循环次数的计数器,默认从1开始计数,可以在velocity.properties文件中修改其初始值

    3.3 条件控制语法

    在Velocity中可以使用条件语法对流程进行控制

    #if(condition)
    ...dosonmething...
    #elseif(condition)
    ...dosomething...
    #else
    ...dosomething...
    #end
    

    3.4 宏

    在Velocity中也有宏的概念,可以将其作为函数来理解,使用#macro声明宏

    ## 声明宏
    #macro(sayHello $name)
       hello $name
    #end
    ## 使用宏
    #sayHello("NICK")
    

    3.5 parse和include指令

    在Velocity中可以通过parse或者include指令引入外部vm文件,但是二者存在区别:include指令会将外部文件原样输出,而parse指令会先对其进行解析再输出(即对外部文件中的vm语法解析)

    #parse("header.vm")
    #include("footer.vm")
    

    4. 在web项目中使用Velocity

    velocity只是一个模板引擎,在web项目中使用Velocity还得添加一个HTTP框架来处理请求和转发,apache提供了velocity-tools,其提供了VelocityViewServlet,也可继承VelocityViewServlet,从而实现自己的HTTP框架
    一般都是继承VelocityViewServlet,重写handleRequest方法,在其中存入公共的参数.

    通过继承或直接使用VelocityViewServlet,可以在管理的vm文件中获得request、session与application对象,也可以直接获取在这几个域对象中保存的值,获取的顺序与EL表达式获取的顺序类似:

    ${request} --> ${session} --> ${application}
    

    比如${testArr},获取testArr属性,velocity会在velocity的context中寻找。没找到在request域中找,没找到在session中找.

    下面将通过实例的方式讲解如何在web项目中使用Velocity
    首先引入velocity-tools及其依赖的相关jar包,然后分为如下4步:

    4.1 继承VelocityViewServlet

    通过继承VelocityViewServlet重写handleRequest方法,可以自定义转发规则

    public class MyVelocityViewServlet extends VelocityViewServlet {
        @Override
        protected Template handleRequest(HttpServletRequest request, HttpServletResponse response, Context ctx) {
            // 往Context容器存放变量
            ctx.put("fullName","lixiaolin");
            // 也可以往request域中存值
            request.setAttribute("anotherName","xlli");
            // forward到指定模板
            return getTemplate("test.vm");
        }
    }
    

    4.2 配置web.xml

    对自定义的VelocityViewServlet配置就像配置普通的Servlet一样,如下:

    <servlet>
        <servlet-name>MyVelocityServlet</servlet-name>
        <servlet-class>com.lxl.velocity.MyVelocityViewServlet</servlet-class>
    </servlet>
    <servlet-mapping>
        <servlet-name>MyVelocityServlet</servlet-name>
        <url-pattern>/servlet/myVelocityServlet</url-pattern>
    </servlet-mapping>
    

    4.3 编写vm文件

    vm文件是作为jsp的替代来展示给用户,在vm文件中可以获得在Context域或request等域中存放的值。默认情况下,会在资源根路径下搜索vm文件,所以直接将vm放在根路径下即可(也可以通过配置velocity.properties指定加载路径)
    如下:

    #set($greet = "hello")
    <!doctype html>
    <html lang="en">
    <head>
        <meta charset="UTF-8">
        <title>Document</title>
    </head>
    <body>
     <p>$!{greet} $!{fullName}</p>
     <p>my another name is $!{anotherName}</p>
    </body>
    </html>
    

    4.4 配置velocity.properties

    通过配置velocity.properties文件,可以自定义vm文件加载方式,指定编码等。当然,也可以不配置velocity.properties,使用缺省的值即可.

    ## 设置模板文件加载器,webapp从应用根目录加载
    resource.loader = webapp
    webapp.resource.loader.class = org.apache.velocity.tools.view.WebappResourceLoader
    ## 模板路径,根目录下的vm文件夹
    webapp.resource.loader.path = /vm
    ## 设置编码
    input.encoding = UTF-8
    output.encoding = UTF-8
    

    最后,在浏览器中访问http://localhost:8080/VelocityApp/servlet/myVelocityServlet即可

    5. 使用VelocityLayoutServlet

    在web站点开发的过程中,经常会碰到几个页面的布局大致相同,比如引用相同的头部和尾部、左侧边栏相同等,在使用jsp开发时我们可以将头部等公共文件抽离出来,然后在实际页面中引入。Velocity也提供了类似的功能,并且该功能更加强大.

    apache提供了VelocityLayoutServlet来实现页面布局,它是VelocityViewServlet的子类,通过使用VelocityLayoutServlet可以简化velocity下页面布局开发,可以使当forward到一个vm页面时,把该页面作为一个已有页面布局的一部分整体显示出来,比如访问资料页面,能够自动把头、尾部显示出来

    velocity-tools包中已经包含了这个类,其使用分为如下几步:

    5.1 配置velocity.properties

    在/WEB-INF/路径下配置velocity.properties文件,指定模板布局文件的位置

    input.encoding=UTF-8
    output.encoding=UTF-8
    ## 定义加载器
    resource.loader=webapp
    webapp.resource.loader.cache=false
    ## 布局文件夹位置
    tools.view.servlet.layout.directory = /templates/layout
    ## 定义默认布局文件
    tools.view.servlet.layout.default.template = layout.vm
    ## 错误模板文件
    tools.view.servlet.error.template = err.vm
    

    5.2 布局母版vm文件

    布局layout.vm文件是所有要展示的vm文件的母版,如下所示:

    <!doctype html>
    <html lang="en">
    <head>
        <meta charset="UTF-8">
        <title>${page_title}</title>
    #if($!{CSS})
     #foreach($_css in ${CSS})
       <link type="text/css" rel="stylesheet" href="${ContextPath}/$_css">
     #end
    #end
    </head>
    <body>
      <div class="header">
          #parse("/templates/layout/header.vm")
      </div>
      <div class="container">
          <div class="sub">
              #parse($sub)
          </div>
          <div class="main">
              $screen_content
          </div>
      </div>
    #if($!JS)
     #foreach($_js in $JS)
       <script type="text/javascript" src="${CntextPath}/${_js}">
     #end
    #end
    </body>
    </html>
    

    其中,有个特殊的变量 screen_content,这是Velocity内置的变量,代表将要转发的页面
    5.3 编写转发的vm文件

    #set($layout = "/templates/layout/layout.vm")
    #set($CSS = ["scripts/css/index.css"])
    #set($JS = ["scripts/js/jquery-1.11.3.js"])
    #set($page_title = "主页")
    #set($sub = "/templates/sub.vm")
    
    <div id="main-show">
        this is main-show
    </div>
    

    5.4 继承VelocityLayoutServlet

    public class MyLayoutServlet extends VelocityLayoutServlet {
        @Override
        protected void doRequest(HttpServletRequest request, HttpServletResponse response) throws IOException {
            // 设置通用的变量
            request.setAttribute("Request", request);
            request.setAttribute("ContextPath", request.getContextPath());
            request.setAttribute("BasePath", request.getScheme() + "://" + request.getServerName() + ":" + request.getServerPort() + request.getContextPath());
    
            long runtime = System.currentTimeMillis();
            super.doRequest(request, response);
    
            if (request.getAttribute("close_comment") == null) {
                Date cur_time = Calendar.getInstance(request.getLocale()).getTime();
                PrintWriter pw = response.getWriter();
                pw.print("\r\n<!-- Generated by VelocityApp Server(");
                pw.print(cur_time);
                pw.print(") Cost ");
                pw.print(cur_time.getTime() - runtime);
                pw.print(" ms -->");
                pw.flush();
                pw.close();
            }
        }
    }
    

    链接:https://www.jianshu.com/p/5913903324ff

    展开全文
  • velocity教程

    2018-04-01 10:46:16
    Velocity是一个基于Java的模板引擎,通过特定的语法,Velocity可以获取java语言中定义的对象,从而实现界面和java代码的真正分离,这意味着可以使用velocity替代jsp的开发模式了(实际上笔者所在的公司已经这么做了...
  • velocity语法

    2019-04-09 17:14:11
    velocity,是一个基于Java的模板引擎,它允许任何人仅仅简单的使用模板语言来引用由java代码定义的对象。 当Velocity应用于web开发时,界面设计人员可以和java程序开发人员同步开发一个遵循MVC架构的web站点。这是很...
  • Velocity的学习1

    2019-04-25 11:15:00
    Velocity 是一个基于Java的的模板引擎,通过特定的语法,速度可以获取在的Java语言中定义的对象,从而实现界面和Java的代码的真正分离,这意味着可以使用Velocity替代JSP的...Cayenne是一个OpenSource Java对象关系...
  • springmvc集成velocity

    2018-09-19 10:06:42
    velocity是一个基于java的模板引擎,通过特定的语法,可以获取到在java中定义的对象,从而实现页面与java代码的分离。由于JSP需要先转换为Servlet,然后编译为class执行,导致效率较低。在访问量较大时表现较差,...
  • Velocity学习3

    2019-04-25 12:53:00
    Apache的速度是一个基于Java的的模板引擎(模板引擎),它允许任何人仅仅简单的使用模板语言(模板语言)来引用由java的代码定义的对象。 官网介绍如下: Velocity是一个模板引擎,可用于多种用途。一些使用...
  • Velocity是一个基于Java的模板引擎,通过特定的语法,Velocity可以获取java语言中定义的对象,从而实现界面和java代码的真正分离,这意味着可以使用velocity替代jsp的开发模式了(实际上笔者所在的公司已经这么做了...
  • Velocity快速入门教程

    2017-02-20 22:54:29
    Velocity是一个基于Java的模板引擎,通过特定的语法,Velocity可以获取java语言中定义的对象,从而实现界面和java代码的真正分离,这意味着可以使用velocity替代jsp的开发模式了(实际上笔者所在的公司已经这么做了...
  • Velocity教程【转】

    2018-02-27 22:16:00
    Velocity是一个基于Java的模板引擎,通过特定的语法,Velocity可以获取java语言中定义的对象,从而实现界面和java代码的真正分离,这意味着可以使用velocity替代jsp的开发模式了(实际上笔者所在的公司已经这么做了...
  • 1、velocity简介: velocity是一个java模板引擎技术,任何人可以使用这种简单而又强有力的模板语言去获取java对象。 在使用Velocity进行web开发时,web开发人员和java程序员可以同时根据Model-View-Controller(MVC...
  • Velocity教程 (zhuan)

    2016-11-01 17:12:00
    **************************************************************** ...Velocity是一个基于Java的模板引擎,通过特定的语法,Velocity可以获取java语言中定义的对象,从而实现界面和java代码的真正...
  • Velocity是一个基于Java的模板引擎,通过特定的语法,Velocity可以获取java语言中定义的对象,从而实现界面和java代码的真正分离,这意味着可以使用velocity替代jsp的开发模式了。这使得前端开发人员可以和 Java ...
  • 在web开发中,经常会遇到一个需求是,判断变量为空(null)或者空字符串(""),从而影响页面的展示逻辑,velocity中有相应的方法可以判断。当然也可以在java后端转化到有效值再判断。 对象为空 #if($lottery) 对象不...
  • VTL是为了提供一种最简单的、最容易的、最简洁的方法来展现web页面中的动态内容。即使是一个只有很少的...变量是一种引用,它能够指向一个Java代码中定义的对象,也可以从页面本身的VTL语句中获取值。下面就是一个可

空空如也

空空如也

1 2 3
收藏数 50
精华内容 20
关键字:

java对象velocity获取

java 订阅