1. 程式人生 > >springmvc整合velocity

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,它也可以被當作一個獨立工具來產生原始碼和報告,或者作為其他系統的整合元件使用。

  1. 先介紹一下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中可以直接呼叫。例如
requestresponse、session使msg內的訊息工具訪問struts的國際化資源,達到簡便實現國際化方法。

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

  1. 使用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