Velocity的學習1

Velocity

是一個基於Java的的模板引擎,經過特定的語法,速度能夠獲取在的Java語言中定義的對象,從而實現界面和Java的代碼的真正分離,這意味着可使用Velocity替代JSP的開發模式了(實際上筆者所在的公司正在開發基於Cayenne的Velocity產品)。javascript

Cayenne O / R.php

Cayenne是一個OpenSource Java對象關係套件,提供運行時O / R框架和Swing GUI映射/部署工具。Velocity用做GUI或Ant任務中基於模板的類生成的引擎。css

 

 

這使得前端開發人員能夠和Java程序開發人員同步開發一個遵循MVC架構的網站點,在實際應用中,Velocity還能夠應用於不少其餘的場景。html

1. Velocity的介紹

Velocity是一個基於Java的的模板引擎,其提供了一個上下文容器,在Java的代碼裏面咱們能夠往容器中存值(MVC的模型中,咱們往ActionForm裏面進行set值,JSP頁面自動映射form的數據),而後在虛擬機文件中使用特定的語法獲取,這是Velocity基本的用法,其與JSP,freemarker並稱爲三大視圖展示技術,相對於JSP而言,Velocity對先後端的分離更加完全:在VM文件中不容許出現的java代碼,而JSP文件中卻能夠。前端

2. Velocty的基本用法java

在這裏咱們以一個HelloVelocity做爲速度的入門實例。在首先apache官網下載velocity的最新發布包,新建普通的java項目,引入其中的速度-1.7.jar和LIB文件夾下的全部罐包便可。而後分爲以下兩步:python

2.1初始化速度引擎

編寫HelloVelocity.java文件以下:jquery

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()); } 

首先,咱們在代碼中初始化了VelocityEngine這個模板引擎,對其設置參數進行初始化,指定使用ClasspathResourceLoader來加載虛擬機文件。web

而後咱們就能夠往VelocityContext這個Velocity容器中存放對象了,在虛擬機文件中咱們能夠取出這些變量,從而進行模板輸出。apache

2.2編寫hellovelocity.vm文件

其中,虛擬機文件放在類路徑目錄下便可,類加載器會進行加載
hellovelocity.vm文件以下:

#set($greet = 'hello') $greet $name #foreach($i in $list) $i #end 

控制檯輸出以下:

hello Velocity
1
2

2.3 Velocity的基本語法

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

3.1變量

在速度中也有變量的概念,使用$符聲明變量,能夠聲明變量也能夠對變量進行賦值(變量是弱類型的)。​​另外還可使用$取出在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]) 

須要注意,上面代碼中$!{}的寫法,使用$ vari獲取變量時,若是變量不存在,Velocity引擎會將其原樣輸出,經過使用$!{}的形式能夠將不存在的變量變成空白輸出。

3.2循環

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

#foreach($item in $list) $item $velocityCount #end 

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

velocity.properties

 

counter.name = velocityCount

counter.initial.value = 1

 

3.3條件控制語法

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

#if(condition) ...dosonmething... #elseif(condition) ...dosomething... #else ...dosomething... #end 

3.4宏

Velocity中也有宏的概念,能夠將其做爲函數來理解,使用#macro聲明宏

## 聲明宏 #macro(sayHello $name) hello $name #end ## 使用宏 #sayHello("NICK") 

3.5解析和包含指令

Velocity中能夠經過解析

parse

或者包括指令include引入外部VM文件,可是兩者存在區別:包括指令會將外部文件原樣輸出,而解析指令會先對其進行解析再輸出(即對外部文件中的VM語法解析)

#parse("header.vm") #include("footer.vm") 

4.在web項目中使用Velocity

velocity只是一個模板引擎,在web項目中使用Velocity還得添加一個HTTP框架來處理請求和轉發,apache提供了velocity-tools,其提供了VelocityViewServlet,也可繼承VelocityViewServlet,從而實現本身的HTTP框架
通常都是繼承的VelocityViewServlet,重寫的handleRequest方法,在其中存入公共的參數。

經過繼承或直接使用VelocityViewServlet,能夠在管理的vm文件中得到請求,會話與應用程序對象,也能夠直接獲取在這幾個域對象中保存的值,獲取的順序與EL表達式獲取的順序相似:
${request}- - > ${session}- > ${application}
好比${testArr}獲取testArr屬性,速度會在速度的上下文中尋找沒找到在請求域中找,沒找到在會話中找。

下面將經過實例的方式講解如何在網絡項目中使用速度
首先引入速度的工具依賴及其的相關的jar包,而後分爲以下4步:

4.1繼承VelocityViewServlet

經過繼承的VelocityViewServlet重寫的handleRequest方法,能夠自定義轉發規則

public class MyVelocityViewServlet extends VelocityViewServlet { @Override protected Template handleRequest(HttpServletRequest request, HttpServletResponse response, Context ctx) { // 往Context容器存放變量 ctx.put("fullName","lixiaolin"); // 也能夠往request域中存值 request.setAttribute("anotherName","xlli"); // forward到指定模板 return getTemplate("test.vm"); } } 

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> 

4.3編寫vm文件

VM文件是做爲JSP的替代來展現給用戶,在VM文件中能夠得到在上下文域或請求等域中存放的值。默認狀況下,會在資源根路徑下搜索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> 

4.4配置velocity.properties

經過配置velocity.properties文件,能夠自定義虛擬機文件加載方式,指定編碼等。固然,也能夠不配置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 

最後,瀏覽在器中訪問http://localhost:8080/VelocityApp/servlet/myVelocityServlet便可

5.使用VelocityLayoutServlet

在網絡站點開發的過程當中,常常會碰到幾個頁面的佈局大體相同,好比引用相同的頭部和尾部,左側邊欄相同等,在使用JSP開發時咱們能夠將頭部等公共文件抽離出來,而後在實際頁面中引入.Velocity也提供了相似的功能,而且該功能更增強大。

apache提供了VelocityLayoutServlet來實現頁面佈局,它是的VelocityViewServlet的子類,經過使用VelocityLayoutServlet能夠簡化Velocity下頁面佈局開發,可使當向前到一個VM頁面時,把該頁面做爲一個已有頁面佈局的一部分總體顯示出來,好比訪問資料頁面,可以自動把頭,尾部顯示出來

Velocity的工具包中已經包含了這個類,其使用分爲以下幾步:

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 

5.2佈局母版vm文件

佈局layout.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> 

其中,有個特殊的變量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> 

5.4繼承VelocityLayoutServlet

public class MyLayoutServlet extends VelocityLayoutServlet { @Override protected 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(); } } } 

6.附錄及參考文獻

參考文獻

相關文章
相關標籤/搜索