Velocity模板引擎介紹

整理下Velocity使用方法,整理比較詳細用例

 

1 Velocity基礎語法

1.1 用戶和開發人員參考文檔

http://velocity.apache.org/engine/releases/velocity-1.7/developer-guide.htmlhtml

 

1.2 註釋

1.行級註釋##java

2.多行註釋#*  *#web

 

1.3 變量定義

使用$開頭的字符串是變量定義,例如$var1, $var2,apache

 

1.4 賦值

使用#set爲變量賦值,例如數組

Java代碼  session

  1. #set($var1 = 100)  
  2. #set($str="foobar")  
  3. #set($var2 = $var1)  
  4. $var2 ##顯示100  

1. #set指令須要使用小括號將賦值語句括起來架構

2. #set語句後面不要加「;」,不然;將解析到頁面上app

3. #set是行級指令,不須要使用#endwebapp

 

1.5 {}含義

假若有一個Velocity變量,例如$abc, 那麼$abcdef這種串如何表達它的含義,即變量$abc的值鏈接def,默認Velocity會認爲$abcdef是一個變量,此時須要使用${abc}def來表達它的含義。jsp

 

1.6 算術運算

1. 運算符: + - * / %

2. 使用#set語句執行算術運算操做

 Java代碼  

  1. #set($a = 5)  
  2. #set($b = 4)  
  3. #set($c = 3)  
  4. #set($d = 2)  
  5. #set($e = 7)  
  6. #set($a= $a+$b*$c/$d - 6%$e) ##5+4*3/2-6%7=5  
  7. "Result:" $a  

1.7 關係運算

> >=  == <= <

 

1.8 邏輯運算

&& || ! 

1.9 條件判斷

Java代碼  

  1. #set($var1 = 20)  
  2. #if($va1 >= 100)  
  3.     $var1 is greater than or equals 100  
  4. #elseif($va1 >= 50)  
  5.     $var1 is betwen [50, 100)  
  6. #elseif($var1 >= 0)  
  7.     $var1 is between [0,50)  
  8. #else  
  9.     $var1 is negative  
  10. #end  

 

1. #if是條件判斷語句,#if/#else, #if/#elseif/#else 是if/else條件判斷語句

2. if/elseif使用括號括起來

3. #if是塊級指令,所以使用#end顯示指定塊級指令的結束 

1.10 循環語句

 Java代碼  

  1. #set($array = [1, "Two", 3,"Four"])  
  2. #foreach($i in $array)  
  3.     <li>  
  4.       The $velocityCount element in the array is $i  
  5.     </li>  
  6. #end  

 

1. 數組定義相似於Javascript,用中括號[]括起來,以逗號分隔

2. $velocityCount是Velocity內置屬性,用於指示當前循環的次數,從1開始計算,即第一次循環,它的值是1

3. #foreach in語句用於表示循環,

4. #foreach語句也是塊級語句,須要使用#end來指明語句的結束

 

1.11  $!的含義

 $!var1的含義是若是變量var1存在,則取其值,不然取空,即不顯示,它等價於以下語句

Java代碼  

  1. #set($var1 = 100)  
  2. $!var2 ##show nothing  
  3. $!var1 ##show 100  
  4.   
  5. #if($var1)  
  6.     $var1  
  7. #end  
  8.   
  9. #if($var2)  
  10. #var2  
  11. #end  

 

1.12  #include指令

 #include能夠在vm中指定靜態文件,這跟JSP的include標籤的含義同樣,例如

#include("staticHTML.html"),這個staticHTML.html

#include指令默認從classpath開始尋找文件??目前不肯定!

 

 

1.13 Velocity資源加載器

在#include指令一節說到了include的文件到什麼位置進行加載,這個位置與velocity資源加載的配置有關,經常使用的加載位置包括 webapp資源加載器,文件路徑資源加載器,還有類路徑記載器,在velocity.properties中,添加以下的配置項表示webapp資源加 載器,項目對於web項目的根開始算起

 

Java代碼  

  1. resource.loader=webapp  
  2. webapp.resource.loader.class=org.apache.velocity.tools.view.WebappResourceLoader  
  3.   
  4. #relative to the web context, under the same parent directory with WEB-INF  
  5. #that is, vm and WEB-INF are sibling folders  
  6. webapp.resource.loader.path=/vm  

 

   其中的webapp是資源加載器的名稱,/vm是web應用的根下面的vm目錄,也就是說,vm目錄和WEB-INF目錄是平級的

Velocity是一個基於java的模板引擎。它容許任何人僅僅簡單的使用模板語言來引用由java代碼定義的對象。

當Velocity應用於web開發時,界面設計人員能夠和java程序開發人員同步開發一個遵循MVC架構的web站點,也就是說,頁面設計人員 能夠只 關注頁面的顯示效果,而由java程序開發人員關注業務邏輯編碼。Velocity將java代碼從web頁面中分離出來,這樣爲web站點的長期維護提 供了便利,同時也爲咱們在JSP和PHP以外又提供了一種可選的方案。

Velocity基本語法和使用:

1. "#"用來標識Velocity的腳本語句。

如:#set、#if 、#else、#foreach、#end、#include、#parse、#macro等。

2. "$"用來標識一個對象(或理解爲PHP的變量)

如:、 

user等。

3. "{}"用來明確標識Velocity變量,和普通模版字符串區分開來;

如:${user}‘s age 能夠顯示爲 riqi's age。

4. "!"強制把不存在的變量顯示爲空白。

如:,假如對象爲空,則模版中不顯示該變量;若是缺乏,則顯示 

msg字符串,這是咱們不想要的結果。

5. 變量的定義和賦值。不須要指定變量的類型,相似弱類型語言PHP能夠隨意指定,在賦值後自動斷定變量的類型,如:

#set($username="riqi") ##設置用戶名

#set($age=26) ##設置年齡

6. 數組循環

#foreach ($user in $users)

    $!{user} $!{velocityCount} <br />

#end

能夠是、或者,提供了獲得循環次數的值: 

velocityCount。

7. 語句註釋

單行註釋:## 單行註釋代碼

多行註釋:#* 多行註釋代碼 *#

8. 模版支持關係和邏輯操做符運算,如:&&、||、! 等

9. 宏定義:#macro ,相似PHP聲明一個函數,其中有函數名稱和參數列表。先定義再調用。

10. 終止命令:#stop,相似PHP的exit(); 中止執行模板引擎並返回。

11. 引入公共模版文件:#include與#parse,它們的差別是:

(1) 與#include不一樣的是,#parse只能指定單個對象。而#include能夠有多個

若是您須要引入多個文件,能夠用逗號分隔就行:

#include ("one.gif", "two.txt", "three.htm" )

在括號內能夠是文件名,可是更多的時候是使用變量的:

#include ( 「greetings.txt」, $seasonalstock )

(2) #include被引入文件的內容將不會經過模板引擎解析;

而#parse引入的文件內容Velocity將解析其中的velocity語法並移交給模板,意思就是說至關與把引入的文件copy到文件中。

#parse是能夠遞歸調用的。

12. 轉義字符'\'.

這個和其它語言沒有差別,假如:那麼,表示輸出 

user字符串,\\$user表示輸出\riqi。

13. Velocity內置了一部分java對象 如:、 

response、$session等,在vm模版裏能夠直接調用。

------------------------------------------------------------------------------------

細節整理:

1. Velocity判斷某個變量是否爲空的方式:

1

#if($!變量名)……#else……#end

或者:

1

#if("" == $!varName)……#else……#end

 

2 Velocity與Java互操做

 

Velocity出現的目的用於簡化基於MVC的web應用開發,用於替代JSP標籤技術,那麼Velocity如何訪問Java代碼.本篇繼續以Velocity三http://bit1129.iteye.com/blog/2106142中的例子爲基礎,

 

2.1    POJO

  

Java代碼  

  1. package com.tom.servlets;  
  2.   
  3. public class User {  
  4.     private String name;  
  5.     private String passwd;  
  6.   
  7.   
  8.     public String getName() {  
  9.         return name;  
  10.     }  
  11.   
  12.     public void setName(String name) {  
  13.         this.name = name;  
  14.     }  
  15.   
  16.     public String getPasswd() {  
  17.         return passwd;  
  18.     }  
  19.   
  20.     public void setPasswd(String passwd) {  
  21.         this.passwd = passwd;  
  22.     }  
  23. }  

 

 

2.2    Service

  

Java代碼  

  1. package com.tom.servlets;  
  2.   
  3. public class UserService {  
  4.     public User get(String userId) {  
  5.         User user = new User();  
  6.         user.setName("tom");  
  7.         user.setPasswd("tom_pwd");  
  8.         return user;  
  9.     }  
  10.   
  11.     public User get(Long userId) {  
  12.         User user = new User();  
  13.         user.setName("Jack");  
  14.         user.setPasswd("Jack");  
  15.         return user;  
  16.     }  
  17.       
  18.     public void save() {//用於測試,vm是否能夠調用無參數的方法  
  19.         System.out.println("save is called");  
  20.     }  
  21. }  

  

2.3    Servlet代碼

   

Java代碼  

  1. package com.tom.servlets;  
  2.   
  3. import org.apache.velocity.Template;  
  4. import org.apache.velocity.context.Context;  
  5. import org.apache.velocity.tools.view.VelocityViewServlet;  
  6.   
  7. import javax.servlet.http.HttpServletRequest;  
  8. import javax.servlet.http.HttpServletResponse;  
  9.   
  10. public class TestVelocityViewServlet extends VelocityViewServlet {  
  11.   
  12.     @Override  
  13.     protected Template handleRequest(HttpServletRequest request, HttpServletResponse response, Context ctx) {  
  14.         UserService userService = new UserService();  
  15.         ctx.put("userService" , userService);//把userService對象設置到Context中  
  16.         return getTemplate("obj.vm");  
  17.     }  
  18. }  

 

 

2.4    vm代碼

 

  

Html代碼  

  1. <!--obj.vm-->  
  2. <html>  
  3.     <body>  
  4.         <p>$userService</p> ##call userService's toString method  
  5.         #set($user = $userService.get(0)) ##When call the java method on its object, only string typed parameters can be accepted  
  6.         <p>$user.name</p> ##print #$user.name as it is, because $user can't be resolved  
  7.         <p>$user.getName()</p> ##Equivalent with $user.name  
  8.   
  9.         #set($user = $userService.get("0"))  
  10.         <p>$user.name</p> ##print $$user.name as it is, because $user can't be resolved  
  11.         <p>$user.getName()</p> ##Equivalent with $user.name  
  12.         <p>$user.save()</p> ##$user.save can't be resolved,so vm can't resolve method that takes no parameter  
  13.     </body>  
  14. </html>  

 

2.5    運行結果

com.tom.servlets.UserService@48b4721b

$user.name

$user.getName()

tom

tom

$user.save()

 

2.6     總結

1.能夠經過Velocity將Java的對象注入到Context中,這樣在vm中能夠得到這個注入的Java對象,例子中調用了這個Java對象的toString方法

2.在vm中,僅僅能調用Java對象的帶有String類型參數的方法,這是非性常巨大的侷限,由於在vm中,無法像在JSP中經過<%%>建立Java對象,而後把它做爲參數調用Java的方法

3.對於setter和getter,能夠直接使用屬性進行方法,例如$user.getName和$user.name是等價的,無論User類是否認義了name屬性(好比把User類中的屬性name更名爲xname,getName和setName方法名不變)

4.$user.save()不能正確解析,也就是說,vm只能調用Java對象帶String類型參數的方法(POJO的get方法除外)

3  脫離servlet使用velocity

Java代碼  

  1. package com.tom.velocity;  
  2.   
  3. import java.io.InputStream;  
  4. import java.io.StringWriter;  
  5. import java.util.Properties;  
  6.   
  7. import org.apache.velocity.Template;  
  8. import org.apache.velocity.VelocityContext;  
  9. import org.apache.velocity.app.VelocityEngine;  
  10.   
  11. public class HelloVelocity {  
  12.     public static void main(String[] args) throws Exception {  
  13.   
  14.         //實例化並初始化Velocity模板引擎  
  15.         VelocityEngine ve = new VelocityEngine();  
  16.         Properties p = new Properties();  
  17.         InputStream in  = HelloVelocity.class.getClassLoader().getResourceAsStream("velocity.properties");  
  18.         p.load(in);  
  19.         ve.init(p);  
  20.   
  21.         //從指定目錄下加載自定的vm文件  
  22.         Template t = ve.getTemplate("vm/hello.vm");  
  23.   
  24.         //建立Velocity上下文環境,用於在vm和Java傳值  
  25.         VelocityContext context = new VelocityContext();  
  26.         context.put("name", "tom");  
  27.         context.put("job", "code-farmer");  
  28.   
  29.         //將模板序列化爲字符串文檔,進行打印  
  30.         StringWriter writer = new StringWriter();  
  31.         t.merge(context, writer);  
  32.   
  33.         //將模板引擎解析的結果打印輸出  
  34.         System.out.println(writer.toString());  
  35.   
  36.         //輸出  
  37.         /* 
  38.          <p>name: tom</p> 
  39.          <p>job: code-farmer</p> 
  40.          */  
  41.     }  
  42. }  

 

3.1 velocity.properties文件

 存放在classpath根目錄下,內容:

Java代碼  

  1. resource.loader=class  
  2.   
  3. #Why ClasspathResourceLoader search the vm in the root directory of classpath  
  4. #This means, <class.resource.loader.path> doesn't take effect  
  5. class.resource.loader.class=org.apache.velocity.runtime.resource.loader.ClasspathResourceLoader  
  6.   
  7. class.resource.loader.path=vm  

 

3.2  hello.vm文件

  存放在{classpath根目錄}/vm目錄下。

 

Java代碼  

  1. <p>name: $name</p>  
  2. <p>job: $job</p>  

 

3.3 java中使用詳細實例

3.3.1 模板內容

<?xml version="1.0" encoding="utf-8"?>

<T24 xmlns="http://www.temenos.com/T24/OFSML/130" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.temenos.com/T24/OFSML/130 ofsml13.xsd">

  <ofsmlHeader>

    <requestId>$_utils.uuid()$ofsRequest.getTxCode()</requestId>

    <correlationId/>

  </ofsmlHeader>

  <serviceRequest>

    <securityContext>

      <userName>$ofsRequest.getName()</userName>

      <password>$ofsRequest.getPassword()</password>

      <company>$ofsRequest.getCompany()</company>

    </securityContext>

    <ofsStandardEnquiry name="$ofsRequest.getEnquiryName()">

     #set($struct = $ofsRequest.getStruct)

     #foreach ($item in $ofsRequest.getMessageData())

      #if($_tools.isEmpty($struct) || $_tools.isNotEmpty($struct.get($item.getName())))

       <selectionCriteria operand="$item.getOperator()">

        <fieldName>$item.getName()</fieldName>

        <value>#foreach($vItem in $item.getValue())$vItem #end</value>

       </selectionCriteria>

      #end

     #end

    </ofsStandardEnquiry>

  </serviceRequest>

</T24>

 

3.3.2 重點部分java代碼

// 組合請求消息報文對象

OFSEnquiryRequest ofsRequest = new OFSEnquiryRequest();

ofsRequest.setHeader(msgType + SPLIT_ROW + txCode);

ofsRequest.setName(name);

ofsRequest.setPassword(password);

ofsRequest.setCompany(company);

ofsRequest.setEnquiryName((String) msgHead.get("enquiryName"));

ofsRequest.setStruct(struct);

ofsRequest.setTxCode(txCode);

 

if (null != msgBody && msgBody.containsKey("messageData")) {

     ofsRequest.setMessageData((List<OFSEnquiryReqItem>) msgBody.get("messageData"));

}

 

// 根據模板組合請求xml內容

VelocityContext ctx = new VelocityContext();

ctx.put("_tools", Tools.getInstance());

ctx.put("_utils", VelocityUtil.getInstance());

ctx.put("ofsRequest", ofsRequest);

String ofsmlEqyXml = "";

try {

     // 變量REQ中保存了上面的模板內容

     ofsmlEqyXml = VelocityHelper.getText(REQ, ctx);

} catch (Exception e) {

}

 

4.Velocity模板優缺點

對於大部分的應用來講,使用 FreeMarker 比 Velocity 更簡單,由於 Velocity 還必須編寫一些自定義的toolbox類以及一遍遍重複的編寫一些比較通用的模版代碼,所以也就喪失了剛開始開發時更多的寶貴時間。另外使用工具類和變通的方法在模版引擎中彷佛不是一個很是有效的作法。同時,Velocity 的作法使得在Velocity的模版中大量的跟 Java 對象進行交互,這違反了簡單的原則,儘管你也能夠將代碼轉入控制器中實現。固然,若是你像使用 Velocity 同樣來使用 FreeMarker ,那麼 FreeMarker 也能夠跟 Velocity 同樣簡單。

Velocity 一個優於 FreeMarker 的地方在於它有很普遍的第三方支持以及一個很是龐大的用戶社區,你能夠經過這個社區得到到不少的幫助,相反的 FreeMarker 在這方面要差不少。固然,也有愈來愈多的第三方軟件開始在支持 FreeMarker 。

velocity性能比freemarker好不少,應該是最好的,又看到說性能超過jsp。

相關文章
相關標籤/搜索