Velocity教程【轉】


原文:http://blog.csdn.net/qq_25237663/article/details/52262532

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());
}
 
 
 
         
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20

首先,我們在代碼中初始化了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
 
 
 
         
  • 1
  • 2
  • 3
  • 4
  • 5
  • 1
  • 2
  • 3
  • 4
  • 5

控制台輸出如下:

hello Velocity
1
2
 
 
 
         
  • 1
  • 2
  • 3
  • 1
  • 2
  • 3

2.3 Velocity的基本語法

本文中只簡單的介紹幾個Velocity的基本語法,具體可以參考這篇文章

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])
 
 
 
         
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7

需要注意,上面代碼中 $!{}的寫法,使用$vari獲取變量時,如果變量不存在,Velocity引擎會將其原樣輸出,通過使用\$!{}的形式可以將不存在的變量變成空白輸出.

3.2 循環

在Velocity中可以使用循環語法遍歷集合,語法結構如下:

#foreach($item in $list)
 $item$velocityCount#end
 
 
 
         
  • 1
  • 2
  • 3
  • 4
  • 1
  • 2
  • 3
  • 4

其中,$item代表遍歷的每一項,velocityCount是Velocity提供的用來記錄當前循環次數的計數器,默認從1開始計數,可以在velocity.properties文件中修改其初始值

3.3 條件控制語法

在Velocity中可以使用條件語法對流程進行控制

#if(condition)
...dosonmething...#elseif(condition)
...dosomething...#else...dosomething...#end
 
 
 
         
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7

3.4 宏

在Velocity中也有宏的概念,可以將其作為函數來理解,使用#macro聲明宏

## 聲明宏#macro(sayHello $name)
   hello $name
#end## 使用宏#sayHello("NICK")
 
 
 
         
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6

3.5 parse和include指令

在Velocity中可以通過parse或者include指令引入外部vm文件,但是二者存在區別:include指令會將外部文件原樣輸出,而parse指令會先對其進行解析再輸出(即對外部文件中的vm語法解析)

#parse("header.vm")
#include("footer.vm")
 
 
 
         
  • 1
  • 2
  • 1
  • 2

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 {@Overrideprotected Template handleRequest(HttpServletRequest request, HttpServletResponse response, Context ctx) {
        // 往Context容器存放變量
        ctx.put("fullName","lixiaolin");
        // 也可以往request域中存值
        request.setAttribute("anotherName","xlli");
        // forward到指定模板return getTemplate("test.vm");
    }
}
 
 
 
         
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11

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>
 
 
 
         
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8

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>
 
 
 
         
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12

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
 
 
 
         
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 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
 
 
 
         
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11

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>
 
 
 
         
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30

其中,有個特殊的變量 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>
 
 
 
         
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9

5.4 繼承VelocityLayoutServlet

public class MyLayoutServlet extends VelocityLayoutServlet {@Overrideprotected 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();
        }
    }
}
 
 
 
         
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24

6. 附錄及參考文獻

參考文獻 
使用 Velocity 模板引擎快速生成代碼 
Velocity教程







免責聲明!

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



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