Velocity語法(VM)
1. 變量
(1) 變量的定義 :
#set($name = "hello") 說明:velocity中變量是弱類型的。
當(dāng)使用#set 指令時,括在雙引號中的字面字符串將解析和重新解釋,如下所示:
#set($directoryRoot = "www" )
#set($templateName = "index.vm" )
#set($template = "$directoryRoot/$templateName" )
$template
輸出將會是: www/index.vm
注: 在velocity中使用$2.5這樣的貨幣標(biāo)識是沒有問題得的,因為velocity中的變量總是以一個大寫或者小寫的字母開始的。
(2) 變量規(guī)范的寫法
${name} ,也可以寫成:$name。提倡用前面的寫法。
例如:你希望通過一個變量$vice 來動態(tài)的組織一個字符串。
Jack is a $vicemaniac.
本來變量是 $vice現(xiàn)在卻變成了$vicemaniac,這樣Veloctiy就不知道您到底要什么了。所以,應(yīng)該使用規(guī)范的格式書寫 : Jack is a ${vice}maniac
現(xiàn)在Velocity知道變量是$vice而不是$vicemaniac。
注意:當(dāng)引用屬性的時候不能加{}
(3) 變量的賦值:
$name="hello"
賦值的左邊必須是一個變量或者是屬性引用。右邊可以是下面六種類型之一:
變量引用,字面字符串,屬性引用,方法引用,字面數(shù)字,數(shù)組列表。
下面的例子演示了上述的每種類型:
#set( $monkey = $bill ) ## variable reference
#set( $monkey.Friend = "monica" ) ## string
#set( $monkey.Blame = $whitehouse.Leak ) ## property reference
#set( $monkey.Plan = $spindoctor.weave($web) ) ## method reference
#set( $monkey.Number = 123 ) ##number
#set( $monkey.Say = ["Not", $my, "fault"] ) ## ArrayList
注意: ①如果上述例子中的右值是null, 則左值不會被賦值,也就是說會保留以前的值。
②velocity模板中未被定義的變量將被認(rèn)為是一個字符串。例如:
#set($foo = "gibbous")
$moon = $foo
輸出結(jié)果為:
$moon = gibbous
③ velocity 模板中不會將 reference 解釋為對象的實(shí)例變量。例如: $foo.Name 將被解釋為 Foo 對象的 getName ()方法,而不是 Foo 對象的 Name 實(shí)例變量。例如:
$ foo.getBar() 等同于 $ foo.Bar ;
$ data.getUser("jon") 等同于 $ data.User("jon") ;
data.getRequest().getServerName() 等同于
$ data.Request.ServerName 等同于 $ {data.Request.ServerName}
2. 循環(huán)
#foreach ($element in $list)
This is $element.
$velocityCount
#end
例子:
#set( $list = ["pine", "oak", "maple"])
#foreach ( $ element in $ list)
$velocityCount
This is $ element.<br>
#end
輸出的結(jié)果為:
1 This is pine.
2 This is oak.
3 This is maple.
每次循環(huán) $list 中的一個值都會賦給 $element 變量。
$list 可以是一個 Vector、 Hashtable 或者 Array 。分配給 $element 的值是一個 java 對象,并且可以通過變量被引用。例如:如果 $element t 是一個 java 的 Product 類,并且這個產(chǎn)品的名字可以通過調(diào)用他的 getName() 方法得到。
#foreach ( $key in $list.keySet())
Key: $key -> Value: $list.get($key) <br>
#end
提示 :velocity中大小寫敏感。
Velocity還特別提供了得到循環(huán)次數(shù)的方法,$velocityCount變量的名字是Velocity默認(rèn)的名字。
例子:
First example:
#foreach ( $foo in [1..5] )
$foo
#end
Second example:
#foreach ( $bar in [2..-2] )
$bar
#end
Third example:
#set ( $arr = [0..1] )
#foreach ( $i in $arr )
$i
#end
上面三個例子的輸出結(jié)果為:
First example :
1 2 3 4 5
Second example :
2 1 0 -1 -2
Third example :
0 1
3. 條件語句
#if (condition)
#elseif (condition)
#else
#end
4. 語句的嵌套
#foreach ($element in $list)
## inner foreach 內(nèi)循環(huán)
#foreach ($element in $list)
This is $element. $velocityCount < br > inner < br >
#end
## inner foreach 內(nèi)循環(huán)結(jié)束
## outer foreach
This is $element.
$velocityCount < br > outer < br >
#end
語句中也可以嵌套其他的語句,如#if…#else…#end等。
5. 注釋
(1)單行注釋:
## This is a single line comment.
(2) 多行注釋:
#*
Thus begins a multi-line comment. Online visitors won’t
see this text because the Velocity Templating Engine will
ignore it.
*#
(3)文檔格式:
#**
This is a VTL comment block and
may be used to store such information
as the document author and versioning
information:
@version 1.1
@author xiao
*#
6. 關(guān)系和邏輯操作符
Velocity 也具有邏輯AND, OR 和 NOT 操作符。
如
## example for AND
#if($foo && $bar)
<strong> This AND that</strong>
#end
例子中#if() 指令僅在$foo 和$bar 斗為真的時候才為真。如果$foo 為假,則表達(dá)式也為假;并且 $bar 將不被求值。如果 $foo 為真,Velocity 模板引擎將繼續(xù)檢查$bar的值,如果 $bar 為真,則整個表達(dá)式為真。并且輸出This AND that 。如果 $bar 為假,將沒有輸出因為整個表達(dá)式為假。
7.Velocity 中的宏
Velocity中的 宏我們可以理解為函數(shù)。
①宏的定義
#macro(宏的名稱 $參數(shù)1 $參數(shù)2 …)
語句體(即函數(shù)體)
#end
②宏的調(diào)用
#宏的名稱($參數(shù)1 $參數(shù)2 …)
說明:參數(shù)之間用空格隔開。
8. #stop
停止執(zhí)行模板引擎并返回,把它應(yīng)用于debug是很有幫助的。
9.#include 與#parse
#include和#parse的作用 都是 引入本地文件, 為了安全的原因,被引入的本地文件只能在TEMPLATE_ROOT目錄下。
區(qū)別:
(1) 與#include不同的是,#parse只能指定單個對象。而#include可以有多個
如果您需要引入多個文件,可以用逗號分隔就行:
#include ( " one.gif " , " two.txt " , " three.htm " )
在括號內(nèi)可以是文件名,但是更多的時候是使用變量的:
#include ( “greetings.txt”, $seasonalstock )
(2) #include被引入文件的內(nèi)容將不會通過模板引擎解析;
而#parse 引入的文件內(nèi)容 Velocity 將解析其中的 velocity 語法并移交給模板,意思就是說相當(dāng)與把引入的文件 copy 到文件中。
#parse是可以遞歸調(diào)用的,例如:如果dofoo.vm包含如下行:
Count down.<br>
#set ($count = 8)
#parse ("parsefoo.vm")
<br>All done with dofoo.vm!
那么在parsefoo.vm模板中,你可以包含如下VTL:
$count
#set($count = $count - 1)
#if ( $count > 0 )<br>
#parse( "parsefoo.vm" )
#else
<br>All done with parsefoo.vm!
#end 的顯示結(jié)果為:
Count down.
8
7
6
5
4
3
2
1
0
All done with parsefoo.vm!
All done with dofoo.vm!
注意:在 vm中使用#parse來嵌套另外一個vm時的變量共享問題。如:
->a.vm 里嵌套 b.vm;
->a.vm 里定義了變量 $param;
->b.vm 里可以直接使用$param,無任何限制。
但需要特別注意的是,如果b.vm里同時定義有變量$param,則b.vm里將使用b.vm里定義的值。
10.轉(zhuǎn)義字符'\'的使用
如果reference被定義,兩個’\’意味著輸出一個’\’,如果未被定義,剛按原樣輸出。如:
#set($email = "foo" )
$email
\$email
\\$email
\\\$email
輸出:
foo
$email
\foo
\$email
如果 $email 未定義
$email
\$email
\\$email
\\\$email
輸出:
$email
\$email
\\$email
\\$email
11. 內(nèi)置對象
Velocity內(nèi)置了一些對象,在vm模版里可以直接調(diào)用,列舉如下:
$request、$response、$session,另外,模板內(nèi)還可以使用 $msg內(nèi)的消息工具訪問 Struts 的國際化資源,達(dá)到簡便實(shí)現(xiàn)國際化的方法。
12. 數(shù)組訪問
對數(shù)組的訪問在Velocity 中存在問題,因為Velocity只能訪問對象的方法,而數(shù)組又是一個特殊的Array,所以雖然數(shù)組可以進(jìn)行循環(huán)列舉,但卻不能定位訪問特定位置的元素,如 strs[2],數(shù)組對固定位置元素的訪問調(diào)用了Array的反射方法get(Object array, int index),而Velocity沒能提供這樣的訪問,所以數(shù)組要么改成List等其他類容器的方式來包裝,要么就通過公用Util類的方式來提供,傳入數(shù)組對象和要訪問的位置參數(shù),從而達(dá)到返回所需值的目的。
示例部分
1.Hello world的示例代碼:
(1)Velocity模板 (hello.html)
<!DOCTYPE HTML PUBLIC "-//W 3C //DTD HTML 4.0 Transitional//EN">
<HTML>
<HEAD>
<TITLE> New Document </TITLE>
</HEAD>
<BODY>
hello,$name! (注意:這里的name與VelocityTest.java中的名稱要一致)
</BODY>
</HTML>
(2)將velocity模板的內(nèi)容轉(zhuǎn)換的類(VelocityTest.java)
import java.io.File;
import java.io.FileOutputStream;
import java.io.PrintWriter;
import java.io.Writer;
import org.apache.velocity.Template;
import org.apache.velocity.VelocityContext;
import org.apache.velocity.app.Velocity;
import org.apache.velocity.app.VelocityEngine;
/**
* Velocity轉(zhuǎn)換
* @author
*/
public class VelocityTest
{
/**
* 主函數(shù)
* @param args
*/
public static void main(String[] args)
{
//獲取模板引擎
VelocityEngine ve = new VelocityEngine();
//模板文件所在的路徑
String path = "D:/java/jproject/regedit/webroot";
//設(shè)置參數(shù)
ve.setProperty(Velocity.FILE_RESOURCE_LOADER_PATH, path);
//處理中文問題
ve.setProperty(Velocity.INPUT_ENCODING,"GBK");
ve.setProperty(Velocity.OUTPUT_ENCODING,"GBK");
try
{
//初始化模板
ve.init();
//獲取模板(hello.html)
Velocity 模板的名稱
Template template = ve.getTemplate("hello.html");
//獲取上下文
VelocityContext root = new VelocityContext();
//把數(shù)據(jù)填入上下文
root.put("name","world"); (注意:與上面的對應(yīng))
//輸出路徑
Strint outpath = "e:/helloworld.html";
//輸出
Writer mywriter = new PrintWriter(new FileOutputStream(
new File(outpath)));
template.merge(root, mywriter);
mywriter.flush();
}
catch (Exception e)
{
e.printStackTrace();
}
}
}
(3)環(huán)境的搭建
在lib目錄內(nèi)分別copy 進(jìn):velocity-1.4.jar,velocity-dept.jar;
下載地址:http://jakarta.apache.org/velocity/
(4)運(yùn)行后的結(jié)果如下:
<!DOCTYPE HTML PUBLIC "-//W 3C //DTD HTML 4.0 Transitional//EN">
<HTML>
<HEAD>
<TITLE> New Document </TITLE>
</HEAD>
<BODY>
hello,world!
</BODY>
</HTML>
2. Servlet和Velocity結(jié)合 示例
(1)example.html
<html>
<head><title>Velocity</title></head>
<body bgcolor="#ffffff">
<center>
<h2>Welcom to Velocity!</h2>
<i>Here's the list of people</i>
<table cellspacing="0" cellpadding="5" width="20%" >
<tr>
<td bgcolor="#eeeeee" align="center">
Names:
</td>
</tr>
#foreach ($name in $theList)
<tr>
<td bgcolor="#eeeeee" align="center">$name</td>
</tr>
#end
</table>
</center>
</body>
</html>
(2)servlet
package com.koal.velocity;
import java.io.IOException;
import java.io.FileNotFoundException;
import java.util.ArrayList;
import java.util.Properties;
import java.util.Vector;
import javax.servlet.ServletConfig;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.apache.velocity.Template;
import org.apache.velocity.context.Context;
import org.apache.velocity.servlet.VelocityServlet;
import org.apache.velocity.app.Velocity;
import org.apache.velocity.exception.ResourceNotFoundException;
import org.apache.velocity.exception.ParseErrorException;
public class SampleServlet extends VelocityServlet
{
/**
* 由VelocityServlet.init()調(diào)用,
* 在此找出模版的路徑
*/
protected Properties loadConfiguration(ServletConfig config )
throws IOException, FileNotFoundException {
Properties p = new Properties();
//取得路徑
String path = config.getServletContext().getRealPath("/");
if (path == null)
{
System.out.println(" SampleServlet.loadConfiguration() : unable to "
+ "get the current webapp root. Using '/'. Please fix.");
path = "/";
}
//設(shè)置路徑
p.setProperty( Velocity.FILE_RESOURCE_LOADER_PATH, path);
return p;
}
/**
* Velocity主要的商業(yè)邏輯處理方法,由VelocityServlet自動調(diào)用
* @param ctx 模板上下文
* @return Template 模板信息
*/
public Template handleRequest( HttpServletRequest request,
HttpServletResponse response, Context ctx )
{
//主要在此設(shè)置演示用的數(shù)據(jù),開發(fā)中在此調(diào)用相應(yīng)的業(yè)務(wù)處理流程,
//并設(shè)置返回到頁面的數(shù)據(jù)
//待展示的列表數(shù)據(jù)
String p1 = "第一位:LiuDong";
String p2 = "第二位:Liang.xf";
Vector personList = new Vector();
//中文需要轉(zhuǎn)換
try {
personList.addElement(new String(p1.getBytes(), "ISO-8859-1") );
personList.addElement(new String(p2.getBytes(), "ISO-8859-1") );
} catch (Exception e) {
System.out.println("數(shù)據(jù)轉(zhuǎn)換異常:"+e);
}
//設(shè)置數(shù)據(jù),供頁面模版替換成顯示的數(shù)據(jù)
ctx.put("theList", personList );
//定義模板
Template outty = null;
try
{
//取模板
outty = getTemplate("example.html");
}
catch( ParseErrorException pee )
{
System.out.println("SampleServlet: parse error for template " + pee);
}
catch( ResourceNotFoundException rnfe )
{
System.out.println("SampleServlet: template not found " + rnfe);
}
catch( Exception e )
{
System.out.println("Error " + e);
}
return outty;
}
(3)在web.xml中的配置:
<web-app>
<servlet>
<servlet-name>SampleServlet</servlet-name>
<servlet-class>com.koal. velocity .SampleServlet</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>SampleServlet</servlet-name>
<url-pattern>/SampleServlet</url-pattern>
</servlet-mapping>
</web-app>
(4)環(huán)境的搭建
在lib目錄內(nèi)分別 copy進(jìn):commons-collections.jar , velocity- 1.4.jar,velocity-dept.jar;
Tomcat運(yùn)行環(huán)境正常。
啟動Tomcat,在IE上輸入: http://localhost:8080/example ,頁面顯示數(shù)據(jù)列表:
本文來自CSDN博客,轉(zhuǎn)載請標(biāo)明出處:http://blog.csdn.net/mmm123lmj/archive/2009/11/19/4833620.aspx