springmvc整合velocity
先來一段百度百科:
定義:Velocity是一個基於java的模板引擎(template engine)。它允許任何人僅僅使用簡單的模板語言(template language)來引用由java程式碼定義的物件。
應用:當Velocity應用於web開發時,介面設計人員可以和java程式開發人員同步開發一個遵循MVC架構的web站點,也就是說,頁面設計人員可以只關注頁面的顯示效果,而由java程式開發人員關注業務邏輯編碼。Velocity將java程式碼從web頁面中分離出來,這樣為web站點的長期維護提供了便利,同時也為我們在JSP和PHP之外又提供了一種可選的方案。
更多功能:Velocity的能力遠不止web站點開發這個領域,例如,它可以從模板(template)產生SQL和PostScript、XML,它也可以被當作一個獨立工具來產生原始碼和報告,或者作為其他系統的整合元件使用。
- 先介紹一下velocity的語法
velocity三種reference
變數:對java物件的一種字串化表示,返回值呼叫了java的toString()方法的結果。
方法:呼叫的是物件的某個方法,該方法必須是public的,返回值也是toString(),方法的引數也必須為String的。
屬性:除了訪問java的類屬性外,等價於get..()方法。
基本符號
1、“#”來標識velocity的指令碼語句。
2、“$”來標識一個物件(或者變數)。
3、“{}”用來標識velocity變數。
4、“!”用來強制把不存在的變數顯示為空白。
5、用雙引號還是單引號表示,預設“”,可以在stringliterals.interpolate=false改變預設處理方式
**基本語法
1、 變數
#($name="hello")
#($templateName = "index.vm")
#set($template = "$directoryRoot/$templateName")
#template
2、迴圈
#foreach($element in $list)
This is $element
$velocityCount
#end
例如:
#set($list=["pine","oak" ,"maple"])
#foreach($element in $list)
$velocityCount
This is $element.<br>
#end
輸出結果為:
this is pine
this is oak
this is maple
$list
可以為Vector、Hashtable、Array。分配給$element 的值是一個java物件,並且可以通過變數被引用。
例如
#foreach($key in $list.keySet)
Key: $key--->value: $list.get($key) <br>
#end
Velocity 還提供了迴圈次數的方法,$velocityCouont變數的名字是Velocity預設的名字,表示迴圈到第幾次了。
3、條件語句
#if(condition)
#elseif(condition)
#else
#end
例如
#set($arr=["jiayou","jiayou2","jiayou3"])
#foreach($element in $arr )
#if($velocityCount==1)
<div>jiayou</div>
#elseif($velocityCount==2)
<div>jiayou2</div>
#else
<div>jiayou3</div>
#end
#end
4、語句巢狀
#foreach($element in $list)
#foreach($element in $list)
this is $element .$velocity <br>inner<br>
#end
this is $element.$velocity <br>out<br>
#end
5、註釋
單行註釋:##this is single
多行註釋:#* ………*#
文件格式:#*………….#
6、關係和邏輯操作符
&& == || !
#if($foo && $bar)
<strong> This AND that</strong>
#end
7、$include和#parse
#include和#parse的作用都是引入本地檔案,為了安全,被進入的檔案只能在Template_root目錄下。
這兩個引入區別:
1)#include可以引入多個檔案。例如:#include(“one.gif”,”two.txt”,”three.html”)
#parse只能引入指定的單個物件。例如:#parse(“layout/index.vm”)
2)#include引入的檔案內容不會被velocity模板引擎解析。
#parse引入的檔案內容,將解析其中的velocity並交給模板,相當於把引入的檔案內容copy到檔案中。
3)#parse是可以遞迴呼叫的。
8、內建物件
velocity內建了一些物件,在vm中可以直接呼叫。例如
9、陣列訪問
陣列要改成list等其他類容器方式來包裝。
“#”用來標識Velocity的指令碼語句,包括#set、#if 、#else、#end、#foreach、#end、#iinclude、#parse、#macro等;
如:
#if($info.imgs)
<img src="$info.imgs" border=0>
#else
<img src="noPhoto.jpg">
#end
“$”用來標識一個物件(或理解為變數);
如:
$i、$msg、$TagUtil.options(...)
**
“!”用來強制把不存在的變數顯示為空白
如當頁面中包含$msg
,如果msg物件有值,將顯示msg的值,如果不存在msg物件同,則在頁面中將顯示$msg
字元。這是我們不希望的,為了把不存 在的變數或變數值為null的物件顯示為空白,則只需要在變數名前加一個“!”號即可。
如:$!msg
- 使用Spring MVC整合Velocity方式開發
pom:
<dependency>
<groupId>org.apache.velocity</groupId>
<artifactId>velocity</artifactId>
<version>1.6.2</version>
</dependency>
<dependency>
<groupId>org.apache.velocity</groupId>
<artifactId>velocity-tools</artifactId>
<version>2.0</version>
</dependency>
springmvc配置檔案:
<?xml version="1.0" encoding="UTF-8"?>
<!--看到下面的beans這個元素標籤沒有,必須有標籤的宣告 -->
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:context="http://www.springframework.org/schema/context"
xmlns:mvc="http://www.springframework.org/schema/mvc"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context.xsd
http://www.springframework.org/schema/mvc
http://www.springframework.org/schema/mvc/spring-mvc.xsd">
<!-- 對web包中的所有類進行掃描,以完成Bean建立和自動依賴注入的功能 -->
<context:component-scan base-package="qust.thb.*" />
<!-- 支援spring3.0新的mvc註解 -->
<mvc:annotation-driven />
<!-- 啟動Spring MVC的註解功能,完成請求和註解POJO的對映 -->
<bean class="org.springframework.web.servlet.mvc.annotation.AnnotationMethodHandlerAdapter"/>
<!-- ViewResolver -->
<!--
<bean class="org.springframework.web.servlet.view.InternalResourceViewResolver">
<property name="viewClass" value="org.springframework.web.servlet.view.JstlView" />
<property name="prefix" value="/WEB-INF/" />
<property name="suffix" value=".jsp" />
</bean>
-->
<!-- velocitey配置 -->
<bean id="velocityConfig" class="org.springframework.web.servlet.view.velocity.VelocityConfigurer">
<property name="resourceLoaderPath" value="." />
<property name="configLocation" value="classpath:template/velocity.properties" />
<property name="velocityProperties">
<props>
<prop key="input.encoding">UTF-8</prop><!-- 模板引擎的編碼 -->
<prop key="output.encoding">UTF-8</prop><!-- 輸出流編碼 -->
<prop key="contentType">text/html;charset=UTF-8</prop><!-- contentType -->
</props>
</property>
</bean>
<bean id="velocityViewResolver" class="commons.spring.mvc.view.VelocityLayoutWithCommonToolsViewResolver">
<property name="cache" value="false" /><!--是否快取 -->
<property name="suffix" value=".vm" />
<property name="prefix" value="/WEB-INF/" />
<property name="layoutUrl" value="/WEB-INF/layout/default.vm" />
<property name="exposeSpringMacroHelpers" value="true" />
<property name="dateToolAttribute" value="dateTool" />
<property name="numberToolAttribute" value="numberTool" />
<property name="contentType" value="text/html;charset=UTF-8"></property>
<property name="velocityUrl" ref="velocityUrl"></property>
<property name="velocityTools" ref="velocityTools"></property>
</bean>
<!-- 配置tools -->
<bean name="velocityTools" class="java.util.HashMap">
<constructor-arg>
<map>
<entry key="stringUtils">
<bean class="org.apache.commons.lang.StringUtils" />
</entry>
<entry key="dateUtils">
<bean class="org.apache.commons.lang.time.DateUtils" />
</entry>
</map>
</constructor-arg>
</bean>
<bean id="velocityUrl" class="java.util.HashMap">
<constructor-arg>
<map>
<entry key="projectModule">
<bean class="***">
<property name="url" value="http://***/" />
</bean>
</entry>
</map>
</constructor-arg>
</bean>
然後在WEB-INF資料夾下建立velocity.properties檔案:
tools.view.servlet.layout.directory=/WEB-INF/layout/
tools.view.servlet.layout.default.template=default.vm
velocimacro.library.autoreload=true
input.encoding=utf-8
output.encoding=utf-8
strutsfile.resource.loader.cache=true
然後建立一個test.vm檔案內容如下:
<html>
<head>
</head>
<body>
hello $name!
</body>
</html>
寫一個Controller請求返回到test.vm頁面
@RequestMapping(value="/test")
@Controller
public class TestController {
@RequestMapping(value="/index")
public String index(Model model) {
String name = "tester";
model.addAttribute("name", name);
return "test/test";
}
}
layout功能
上面我們使用的是VelocityLayoutWithCommonToolsViewResolver這個物件做為springmvc的檢視解析器,這個物件是集成了layout功能和tool功能為一體的解析器。
對於一個WEB應用來說,頁面的基本結構往往是固定的,頁面中的很多部分,例如頁面統一的頭部、尾部和選單,我們一般是不太需要變化的,各個頁面基本一致,變化的往往是頁面的具體內容部分,這樣,佈局(layout)功能的使用,就能大大減化前端頁面的複雜性了。這裡簡單介紹一下如何使用velocity框架來實現頁面的佈局。
我們知道,要在spring框架中配置velocity,一般需要配置兩個bean,一個是velocityConfig, 別一個則是viewResolver。先來看velocityConfig的配置,基本配置如下所示,這裡和不使用佈局的配置方式沒有任何差別。
1. 一般情況下,當我們不使用velocity的佈局功能時,我們一般會把viewResolver的class配置為:
org.springframework.web.servlet.view.velocity.VelocityViewResolver,當需要使用佈局功能的時候,viewResolver的class需要配置為:
org.springframework.web.servlet.view.velocity.VelocityLayoutViewResolver,顧名思義,從命名中我們就能看出來這個viewResolver是支援layout功能的。
2. 不同的是,這裡多了一個layoutUrl的屬性配置:, 這個配置是設定你的layout檔案的存在路徑,需要注意的是,這個路徑不是相對於webapp路徑來的,而是相對於velocityConfig配置中的resourceLoaderPath屬性配置的路徑(resourceLoaderPath的路徑是相對於webapp的路徑)。
普通的頁面實現:比如我們要輸出一個帶帶固定頁頭和頁尾的頁面,內容就是screen_content的值,知識後使用普通解析器頁面如下
<body>
<div class="content">
#parse("/common/header.vm")
<div class="content-info">
#parse("/common/leftMenu.vm")
<div class="content-main">
$screen_content
</div>
</div>
#parse("common/footer.vm")
</div>
</body>
layout頁面實現:就是指定使用哪個頁面佈局來渲染檢視
#set($layout = "/layout/layout2.vm")
$screen_content