Velocity語(yǔ)法(VM)
1. 變量
(1) 變量的定義 :
#set($name = "hello") 說(shuō)明:velocity中變量是弱類(lèi)型的。
當(dāng)使用#set 指令時(shí),括在雙引號(hào)中的字面字符串將解析和重新解釋?zhuān)缦滤荆?
#set($directoryRoot = "www" )
#set($templateName = "index.vm" )
#set($template = "$directoryRoot/$templateName" )
$template
輸出將會(huì)是: www/index.vm
注: 在velocity中使用$2.5這樣的貨幣標(biāo)識(shí)是沒(méi)有問(wèn)題得的,因?yàn)関elocity中的變量總是以一個(gè)大寫(xiě)或者小寫(xiě)的字母開(kāi)始的。
(2) 變量規(guī)范的寫(xiě)法
${name} ,也可以寫(xiě)成:$name。提倡用前面的寫(xiě)法。
例如:你希望通過(guò)一個(gè)變量$vice 來(lái)動(dòng)態(tài)的組織一個(gè)字符串。
Jack is a $vicemaniac.
本來(lái)變量是 $vice現(xiàn)在卻變成了$vicemaniac,這樣Veloctiy就不知道您到底要什么了。所以,應(yīng)該使用規(guī)范的格式書(shū)寫(xiě) : Jack is a ${vice}maniac
現(xiàn)在Velocity知道變量是$vice而不是$vicemaniac。
注意:當(dāng)引用屬性的時(shí)候不能加{}
(3) 變量的賦值:
$name="hello"
賦值的左邊必須是一個(gè)變量或者是屬性引用。右邊可以是下面六種類(lèi)型之一:
變量引用,字面字符串,屬性引用,方法引用,字面數(shù)字,數(shù)組列表。
下面的例子演示了上述的每種類(lèi)型:
#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, 則左值不會(huì)被賦值,也就是說(shuō)會(huì)保留以前的值。
②velocity模板中未被定義的變量將被認(rèn)為是一個(gè)字符串。例如:
#set($foo = "gibbous")
$moon = $foo
輸出結(jié)果為:
$moon = gibbous
③ velocity 模板中不會(huì)將 reference 解釋為對(duì)象的實(shí)例變量。例如: $foo.Name 將被解釋為 Foo 對(duì)象的 getName ()方法,而不是 Foo 對(duì)象的 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 中的一個(gè)值都會(huì)賦給 $element 變量。
$list 可以是一個(gè) Vector、 Hashtable 或者 Array 。分配給 $element 的值是一個(gè) java 對(duì)象,并且可以通過(guò)變量被引用。例如:如果 $element t 是一個(gè) java 的 Product 類(lèi),并且這個(gè)產(chǎn)品的名字可以通過(guò)調(diào)用他的 getName() 方法得到。
#foreach ( $key in $list.keySet())
Key: $key -> Value: $list.get($key) <br>
#end
提示 :velocity中大小寫(xiě)敏感。
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
上面三個(gè)例子的輸出結(jié)果為:
First example :
1 2 3 4 5
Second example :
2 1 0 -1 -2
Third example :
0 1
3. 條件語(yǔ)句
#if (condition)
#elseif (condition)
#else
#end
4. 語(yǔ)句的嵌套
#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
語(yǔ)句中也可以嵌套其他的語(yǔ)句,如#if…#else…#end等。
5. 注釋
(1)單行注釋?zhuān)?br />
## This is a single line comment.
(2) 多行注釋?zhuān)?br />
#*
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 斗為真的時(shí)候才為真。如果$foo 為假,則表達(dá)式也為假;并且 $bar 將不被求值。如果 $foo 為真,Velocity 模板引擎將繼續(xù)檢查$bar的值,如果 $bar 為真,則整個(gè)表達(dá)式為真。并且輸出This AND that 。如果 $bar 為假,將沒(méi)有輸出因?yàn)檎麄€(gè)表達(dá)式為假。
7.Velocity 中的宏
Velocity中的 宏我們可以理解為函數(shù)。
①宏的定義
#macro(宏的名稱(chēng) $參數(shù)1 $參數(shù)2 …)
語(yǔ)句體(即函數(shù)體)
#end
②宏的調(diào)用
#宏的名稱(chēng)($參數(shù)1 $參數(shù)2 …)
說(shuō)明:參數(shù)之間用空格隔開(kāi)。
8. #stop
停止執(zhí)行模板引擎并返回,把它應(yīng)用于debug是很有幫助的。
9.#include 與#parse
#include和#parse的作用 都是 引入本地文件, 為了安全的原因,被引入的本地文件只能在TEMPLATE_ROOT目錄下。
區(qū)別:
(1) 與#include不同的是,#parse只能指定單個(gè)對(duì)象。而#include可以有多個(gè)
如果您需要引入多個(gè)文件,可以用逗號(hào)分隔就行:
#include ( " one.gif " , " two.txt " , " three.htm " )
在括號(hào)內(nèi)可以是文件名,但是更多的時(shí)候是使用變量的:
#include ( “greetings.txt”, $seasonalstock )
(2) #include被引入文件的內(nèi)容將不會(huì)通過(guò)模板引擎解析;
而#parse 引入的文件內(nèi)容 Velocity 將解析其中的 velocity 語(yǔ)法并移交給模板,意思就是說(shuō)相當(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來(lái)嵌套另外一個(gè)vm時(shí)的變量共享問(wèn)題。如:
->a.vm 里嵌套 b.vm;
->a.vm 里定義了變量 $param;
->b.vm 里可以直接使用$param,無(wú)任何限制。
但需要特別注意的是,如果b.vm里同時(shí)定義有變量$param,則b.vm里將使用b.vm里定義的值。
10.轉(zhuǎn)義字符'\'的使用
如果reference被定義,兩個(gè)’\’意味著輸出一個(gè)’\’,如果未被定義,剛按原樣輸出。如:
#set($email = "foo" )
$email
\$email
\\$email
\\\$email
輸出:
foo
$email
\foo
\$email
如果 $email 未定義
$email
\$email
\\$email
\\\$email
輸出:
$email
\$email
\\$email
\\$email
11. 內(nèi)置對(duì)象
Velocity內(nèi)置了一些對(duì)象,在vm模版里可以直接調(diào)用,列舉如下:
$request、$response、$session,另外,模板內(nèi)還可以使用 $msg內(nèi)的消息工具訪(fǎng)問(wèn) Struts 的國(guó)際化資源,達(dá)到簡(jiǎn)便實(shí)現(xiàn)國(guó)際化的方法。
12. 數(shù)組訪(fǎng)問(wèn)
對(duì)數(shù)組的訪(fǎng)問(wèn)在Velocity 中存在問(wèn)題,因?yàn)閂elocity只能訪(fǎng)問(wèn)對(duì)象的方法,而數(shù)組又是一個(gè)特殊的Array,所以雖然數(shù)組可以進(jìn)行循環(huán)列舉,但卻不能定位訪(fǎng)問(wèn)特定位置的元素,如 strs[2],數(shù)組對(duì)固定位置元素的訪(fǎng)問(wèn)調(diào)用了Array的反射方法get(Object array, int index),而Velocity沒(méi)能提供這樣的訪(fǎng)問(wèn),所以數(shù)組要么改成List等其他類(lèi)容器的方式來(lái)包裝,要么就通過(guò)公用Util類(lèi)的方式來(lái)提供,傳入數(shù)組對(duì)象和要訪(fǎng)問(wèn)的位置參數(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中的名稱(chēng)要一致)
</BODY>
</HTML>
(2)將velocity模板的內(nèi)容轉(zhuǎn)換的類(lèi)(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);
//處理中文問(wèn)題
ve.setProperty(Velocity.INPUT_ENCODING,"GBK");
ve.setProperty(Velocity.OUTPUT_ENCODING,"GBK");
try
{
//初始化模板
ve.init();
//獲取模板(hello.html)
Velocity 模板的名稱(chēng)
Template template = ve.getTemplate("hello.html");
//獲取上下文
VelocityContext root = new VelocityContext();
//把數(shù)據(jù)填入上下文
root.put("name","world"); (注意:與上面的對(duì)應(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自動(dòng)調(diào)用
* @param ctx 模板上下文
* @return Template 模板信息
*/
public Template handleRequest( HttpServletRequest request,
HttpServletResponse response, Context ctx )
{
//主要在此設(shè)置演示用的數(shù)據(jù),開(kāi)發(fā)中在此調(diào)用相應(yīng)的業(yè)務(wù)處理流程,
//并設(shè)置返回到頁(yè)面的數(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ù),供頁(yè)面模版替換成顯示的數(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)境正常。
啟動(dòng)Tomcat,在IE上輸入: http://localhost:8080/example ,頁(yè)面顯示數(shù)據(jù)列表:
本文來(lái)自CSDN博客,轉(zhuǎn)載請(qǐng)標(biāo)明出處:http://blog.csdn.net/mmm123lmj/archive/2009/11/19/4833620.aspx
在Eclipse中遇到The type XXX cannot be resolved. It is indirectly referenced from required .class files錯(cuò)誤.....,查找的解決辦法如下:
一:
It is indirectly referenced from required .class file
原因:你正要使用的類(lèi)調(diào)用了另一個(gè)類(lèi),而這個(gè)類(lèi)又調(diào)用了其他類(lèi),這種關(guān)系可能會(huì)有好多層。而在這個(gè)調(diào)用的過(guò)程中,某個(gè)類(lèi)所在的包的缺失就會(huì)造成以上那個(gè)錯(cuò)誤。
解決方法:導(dǎo)入缺失的包
二:
The project was not built since its build path is incomplete. Cannot find the class file for java.lang.Object. Fix the build path then try building this project
The type java.lang.Object cannot be resolved. It is indirectly referenced from required .class files
出現(xiàn)以上訊息的原因是因?yàn)槟阊b了多個(gè)版本的jre或jdk的關(guān)係。本來(lái)Eclipse在建立專(zhuān)案時(shí),會(huì)自動(dòng)參照你的jre路徑,但多個(gè)版本就沒(méi)辦法了。
你只能手動(dòng)建立…
1. 進(jìn)入window\preferences\java\Installed JREs
1)按Add
2)輸入JRE Name, 例JDK1.5.0.03
3)JRE home directory, 選擇安裝的路徑
4)按OK
2. 進(jìn)入Project\properties\Java Bulid Path
1)Add library
2)選JRE System Library後按Next
3)選workplace default JRE後按finish...
三,the type org.apache.axiom.soap.SOAPEnvelope cannot be resolved,it is indirectly referenced from required .class files
當(dāng)自動(dòng)生成webservice程序時(shí)報(bào)的錯(cuò)誤,最終解決辦法為,把xis2_Codegen_Wizard_1.4.0\lib包全復(fù)制到build path下,問(wèn)題全解決了.
問(wèn)題:An error occurred while completing process,java.lang.reflect.InvocationTargetException
當(dāng)我用axis自動(dòng)生成代碼時(shí),最后一步報(bào)的錯(cuò),網(wǎng)上通常說(shuō)的解決辦法是
從AXIS2的LIB庫(kù)中復(fù)制"geronimo-stax-api_1.0_spec-1.0.1.jar"和"backport-util-concurrent-3.1.jar"文件到Codegen的lib目錄中,同時(shí)修改plugin.xml文件,添加
<library name="lib/geronimo-stax-api_1.0_spec-1.0.1.jar">
<export name="*"/>
</library>
<library name="lib/backport-util-concurrent-3.1.jar">
<export name="*"/>
</library>
到plugin.xml文件中,保存后重新啟動(dòng)Eclipse即可!
但本人用這種辦法,怎么試也不行,本人用的JDK1.4,自動(dòng)生成代碼插件為:Axis2_Codegen_Wizard_1.3.0
所以怎么試也行不通,最后本來(lái)?yè)Q了個(gè).Axis2_Codegen_Wizard_1.4.0問(wèn)題終于解決.也整了一天了!
axis所需要的包:
Axis2_Codegen_Service_1.4.0_plugins 代碼自動(dòng)生成 新建工程時(shí),記得把該文件夾下lib\.jar包全部導(dǎo)入.
獲取XML
JDOM1.0\build\jdom.jar 要加載到lib中
記住,當(dāng)你用JDK1.4時(shí),所有的包都要下載后墜為1.4的包,不然會(huì)出些稀奇古怪的錯(cuò)誤.
webservice操作步驟:
1,把Axis2_Codegen_Service_1.4.0_plugins拷貝到plugin下.
2,打開(kāi)eclipse,新建文件時(shí)選擇axis.
3,選擇JWDL地址.
4,生成代碼,
5,調(diào)用:
TaskServiceStub ts = new TaskServiceStub();
TaskServiceStub.GetTaskList gt = new TaskServiceStub.GetTaskList();
gt.setPassword(usercode);
gt.setUsercode(password);
String sxml = ts.GetTaskList(gt).getGetTaskListResult();
四,
java.net.SocketException: Software caused connection abort: socket write error
at java.net.SocketOutputStream.socketWrite0(Native Method)
at java.net.SocketOutputStream.socketWrite(SocketOutputStream.java:92)
at java.net.SocketOutputStream.write(SocketOutputStream.java:126)
這個(gè)問(wèn)題,我一直找不到答案,希望各位高手能告訴我.