Velocity基礎及使用


概念

velocity是apache的子項目,官網http://velocity.apache.org/,類似於freemarker和jsp,是模板語言。

 

基本配置:

web工程中:

1、引入jar包:

2、web.xml配置:

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

<web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://java.sun.com/xml/ns/javaee" xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd" id="WebApp_ID" version="2.5">

<display-name>velocity_web_test</display-name>

<servlet>

<servlet-name>velocityView</servlet-name>

<servlet-class>org.apache.velocity.tools.view.VelocityViewServlet</servlet-class>

<load-on-startup>10</load-on-startup>

</servlet>

<servlet-mapping>

<servlet-name>velocityView</servlet-name>

<url-pattern>*.vm</url-pattern>

</servlet-mapping>

</web-app>

其中配置了velocity的VelocityViewServlet,攔截*.vm請求。

 

3、寫一個vm文件,如test.vm

<html>

    <head></head>

      

<body>

<table>

 

#set( $treeList = ["pine", "oak", "maple", "redwood"])

<tr><td>Tree Name</td></tr>

#foreach ($name in $treeList)

<tr>

<td>

<b><font color="GREEN">$name</font></b> is a big tree!

</td>

</tr>

#end

 

    </table>

 

</body>

</html>

 

訪問結果:

表示已經成功。

 

velocity使用的語言成為VTL語言,類似於freemark的ftl。

servlet中使用velocity配置:

只用在自己的servlet中繼承基本配置中的VelocityViewServlet即可:

如:

VelocityServlet.java:

package com.test;

 

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.tools.view.VelocityViewServlet;

 

/**

* 測試velocityservlet

*/

public class VelocityServlet extends VelocityViewServlet {

    private static final long serialVersionUID = 1L;

 

    @Override

    protected Template handleRequest(HttpServletRequest request, HttpServletResponse response, Context ctx) {

        ctx.put("username", "anders");

        return getTemplate("test.vm");

 

    }

 

    @Override

    protected void setContentType(HttpServletRequest request, HttpServletResponse response) {

        response.setContentType("text/html;charset=utf-8");

    }

}

然后web.xml配置servlet:

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

<web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"

    xmlns="http://java.sun.com/xml/ns/javaee"

    xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd"

    id="WebApp_ID" version="2.5">

    <display-name>velocity_web_test</display-name>

    <servlet>

        <servlet-name>VelocityServlet</servlet-name>

        <servlet-class>com.test.VelocityServlet</servlet-class>

    </servlet>

    <servlet-mapping>

        <servlet-name>VelocityServlet</servlet-name>

        <url-pattern>/VelocityServlet</url-pattern>

    </servlet-mapping>

</web-app>

 

test.vm:

<html>

    <head></head>

<body>

     hello,$username

</body>

</html>

 

訪問servlet(注意不要直接訪問vm),如:http://localhost/velocity_web_test/VelocityServlet

顯示:

hello, anders

在servlet的handleRequest方法中即可為vm頁面設置需要顯示的變量

 

 

基本用法

設置變量,取變量

#set($a="abc")

     hello,$a

顯示

hello,abc

 

#后面一般接命令,$后面一般接變量

#set($a="abc")表示設置變量a為abc字符串

$a表示顯示變量a的值,所以就是:hello,abc

 

例子:

$data.setUser("jon")

##等同於

#set( $data.User = "jon" )

注釋

單行注釋:

 

## 單行注釋

 

多行注釋:

#*

多行1

多行2

*#

 

取值的方式

取值也叫作引用。

變量命名規則:字母開頭,后面可以是字母、數字、下划線、中划線

取值跟jstl類似,如:

${username}

${user.userName}

還可以直接執行java的方法,如:

 

<body>

     username1: ${user.getUserName()}<br/>

     username2: ${user.setUserName("kkk")}<br/>

     username1: ${user.getUserName()}<br/>

</body>

顯示:

username1: 張三
username2: 
username1: kkk

由於$user.setUserName("kkk ") 是void返回值方法,所以不會顯示任何東西.

 

有大括號的是正規方式引用(取值),也可以使用簡潔方式(去掉大括號),如:

$username

不過一些特殊場合必須加,如有一個vice變量

${vice}hello

如果不加就成了$vicehello,找不到變量了

取值的規則

$customer.address

查找順序是:

1、getaddress()

2、getAddress()

3、get("address")

4、isAddress()

大寫的屬性名Address引用,將是:

1、getAddress()

2、getaddress()

3、get("Address")

4、isAddress()

默認顯示空白

如果取值失敗,默認會原樣顯示,如$user,如果user沒定義,就會直接顯示出來,可以加感嘆號讓他顯示空白,如$!user或者$!{user}

 

set用法

set設置變量

set可以設置各種變量類型,如:

#set( $monkey = $bill ) ## 設置變量

#set( $monkey.Friend = "monica" ) ## 設置字符串

#set( $monkey.Blame = $whitehouse.Leak ) ## 設置變量的屬性

#set( $monkey.Plan = $spindoctor.weave($web) ) ## 設置方法返回值

#set( $monkey.Number = 123 ) ##設置數字

#set( $monkey.Say = ["Not", $my, "fault"] ) ## 設置ArrayList

#set( $monkey.Map = {"banana" : "good", "roast beef" : "bad"}) ## 設置Map

其中ArrayList用中括號,Map用大括號,跟json格式一樣

ArrayList訪問元素:

$monkey.Say.get(0)

Map訪問元素

$monkey.Map.get("bannana")或者$monkey.Map.banana

注:set賦值時,如果賦值失敗或者賦的是null值,都不會生效,如:

 

#set( $result = "kkk" )

$result

<br/>

#set( $result = $user.userName )

$result

此時如果user對象不存在或者user.userName是null,都不會賦值,都輸出

kkk

kkk

 

注:set賦值變量時,如果右邊是單引號,則不會取變量值,原樣輸出,如果是雙引號,則會取出變量值,如:

1、單引號,原樣輸出:

#set($a = "kkk" )

        #set($b = "ggg")

        #set($c = '$a + $b')

$c

輸出:

$a + $b

也可以通過配置來讓他轉義:

velocity.properties such that stringliterals.interpolate=false.

2、雙引號,變量轉義后輸出

 

#set($a = "kkk" )

        #set($b = "ggg")

        #set($c = "$a + $b")

$c

輸出

kkk + ggg

3、沒有符號,做運算

 

#set($a = "kkk" )

        #set($b = "ggg")

        #set($c = $a + $b)

$c

輸出:

kkkggg

set計算

類似於jstl,vtl也能做計算,如:

 

        #set($foo = 5)

        #set($bar = 6)

          

#set( $value = $foo + 1 )

     $value<br/>

     #set( $value = $bar - 1 )

     $value<br/>

     #set( $value = $foo * $bar )

     $value<br/>

     #set( $value = $foo / $bar )

     $value<br/>

輸出:

如果是字符串,則直接拼接,如:

        #set($foo = "5")

        #set($bar = "6")

          

#set( $value = $foo + 1 )

     $value<br/>

     #set( $value = $bar - 1 )

     $value<br/>

     #set( $value = $foo * $bar )

     $value<br/>

     #set( $value = $foo / $bar )

     $value<br/>

輸出:

這里字符串只有+運算,-*/都沒有,所以失敗了,value的值沒變(set賦值失敗,原值不變),只有第一次"5"+"1"成功了,所以輸出4個51

注:單引號跟雙引號一樣,都是字符串拼接

原樣輸出用#liternal() ….#end,不解析vtl

如:

 

        #set($a=5)

        #literal()

${a}

         #end

輸出${a}而不是5

if語句

如后台設置了:

        ctx.put("a", 1);

vm頁面:

        #if($a == '1')

            true enough

        #elseif($a == '2')

            a is 2

        #else

            no way!

        #end

輸出:true enough

另:

$a == '1'

$a == 1

$a == "1"

三個都一樣。

如果if、else等關鍵字前或后緊跟了其他字符,則可以用大括號隔開,如:

#if($a == "1")

            true enough#{else}no way!

     #end

 

注意:判斷條件中如果只有一個變量,則只有當該變量找不到或者為null或者為false時,才不成立,其他時候都成立,如:

1

        #set($a="abc")

        #if($a)

            yes

        #else

            no

        #end

輸出:yes

 

2

        #set($a="abc")

        #if($a.b)

            yes

        #else

            no

        #end

輸出:no

3

        #set($a=false)

        #if($a)

            yes

        #else

            no

        #end

輸出:no

注意:vtl中的所有數據類型都是對象,沒有java中的int等類型,==比較時,都是調用toString方法,int等類型會自動轉成Integer的封裝。

 

支持與或非等語法,如:

        #if($a && $b)

        #if(!($a || $b))

for循環語句

遍歷list(array)

后台代碼:

 

        List<User> users = new ArrayList<User>();

        User user1 = new User("zhangsan", 29);

        User user2 = new User("lisi", 99);

        users.add(user1);

        users.add(user2);

        

        ctx.put("users", users);

        

        return getTemplate("test.vm");

vm代碼:

 

        #foreach($user in $users)

            index:$velocityCount

            username:$user.userName

            age:$user.age

            <br/>

        #end

輸出:

index:1 username:zhangsan age:29 
index:2 username:lisi age:99 

 

其中$velocityCount可以取得當前序號(計數器).

遍歷map

后台代碼:

 

        Map<String, User> usersMap = new HashMap<String, User>();

        User user1 = new User("wangwu", 30);

        User user2 = new User("zhaoliu", 100);

 

        usersMap.put("user1", user1);

        usersMap.put("user2", user2);

        ctx.put("usersMap", usersMap);

        

        return getTemplate("test.vm");

vm代碼:

 

        #foreach($user in $usersMap)

            index:$velocityCount

            username:$user.userName

            age:$user.age

            <br/>

        #end

或者

        #foreach($userKey in $usersMap.keySet())

            index:$velocityCount

            username:$usersMap.get($userKey).userName

            age:$usersMap.get($userKey).age

            <br/>

        #end

輸出:

index:1 username:zhaoliu age:100 
index:2 username:wangwu age:30 

 

$velocityCount的名字、初始值也可以進行配置,如:

directive.foreach.counter.name = myVelocityCount

directive.foreach.counter.initial.value = 100

名字就改成了myVelocityCount,初始值為100

include和parse包含

類似於jsp的include包含,如:

        #include("a.vm")

        #include("b.txt")

        #parse("c.vm")

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

        #include( "greetings.txt", $seasonalstock )

include包含的文件不會被解析,原樣顯示。

parse包含的文件會解析。

是否解析跟包含文件擴展名無關,只跟include還是parse命令有關

 

include可以一次包含多個,也可用變量名指定文件名

parse只能包含一個。

#parse 的模板中還可以再包含#parse聲明,默認的深度為10,這是由配置參數directive.parse.max.depth決定的

stop

stop之后的內容停止輸出(不僅是不解析,而且是所有的文件內容都不輸出),以便用於調試,如:

 

        #set($a = 6)

        $a

        #stop

        abc

        $a
輸出:
6

 

宏調用macro

無參宏

類似於freemarker,可以定義宏,解析之前自動替換內容,再解析,如:

 

        #macro( d )

welcome!

        #end

        

        #d()

輸出:

welcome!

這里用macro定義了名稱為d的宏,然后用#d()調用宏。

注意:宏定義改了之后,需要重啟服務才會生效(調試時需注意)

 

帶參數宏

如例1:

        #macro(d $a $b)

            hello,$a,$b

        #end

        

        #d("zhangsan", "lisi")

輸出:

hello,zhangsan,lisi

 

其中,$a和$b是參數

 

例2:

 

        #macro(d $color $userList)

            color is $color </br>

            #foreach($user in $userList)

                $user <br/>

            #end

        #end

        

        #d("black", ["zhangsan", "lisi", "wangwu"])

輸出:

color is black 
zhangsan 
lisi 
wangwu 

 

這里傳了一個String參數$color和一個Arraylist參數$userList

轉義

引用的轉義

有時需要輸出$、#這些

$2.5輸出:$2.5    不會有問題,因為變量不能以數字開頭

 

斜杠表示轉義:

#set( $email = "foo" )

$email

\$email

\\$email

\\\$email

輸出:

foo

$email

\foo

\$email

\\$email相當於\\ + $email,轉義的斜杠+變量值,所以是\foo

\\\$email相當於\\ + \$email,轉義的斜杠+轉義的變量,所以是\$email

 

如果$email沒有定義,則原樣輸出:

$email

\$email

\\$email

\\$email

命令的轉義

與引用轉義類似,在#號前加斜杠即可,

 

例1:

\#include( "a.txt" )

此時不會引入a.txt而是在頁面上直接輸出#include( "a.txt" )

 

例2:

\\#include ( "a.txt" )

此時輸出\加a.txt的內容。

 

例3:

        \#if( $a )

hello

\#end

輸出:

例4:

        #set($a = true)

        \\#if( $a )

hello

\\#end

輸出:

因為\\被轉義成了\

 

例5:

        #set($a = true)

        \#if( $a )

hello

#end

編譯報錯,因為只有#end,而#if被轉義了。

范圍操作,如:[3..5]等

范圍操作邊界只能是整數,每次遞增(遞減)1.

實質是生成了一個數組,只能用於#foreach或者#set命令標簽。

一般用於網頁設計者設計table等表格時,沒有足夠的填充數據時使用。

 

例1:    

    #foreach($a in [3..-2])

            $a <br/>

        #end

輸出:





-1 
-2

   

例2:    

    #foreach($a in [3..3])

            $a <br/>

        #end

輸出:


例3:

 

        #set($arr = [3..5])

        #foreach($a in $arr)

            $a <br/>

        #end

輸出:



這里把范圍[3..5]賦值給了$arr(實質是生成了一個數組[3,4,5]),再循環遍歷


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM