<rt id="bn8ez"></rt>
<label id="bn8ez"></label>

  • <span id="bn8ez"></span>

    <label id="bn8ez"><meter id="bn8ez"></meter></label>

    Change Dir

    先知cd——熱愛生活是一切藝術(shù)的開始

    統(tǒng)計(jì)

    留言簿(18)

    積分與排名

    “牛”們的博客

    各個(gè)公司技術(shù)

    我的鏈接

    淘寶技術(shù)

    閱讀排行榜

    評(píng)論排行榜

    velocity學(xué)習(xí)筆記(上)

     

    Velocity筆記(上)

    雜七雜八的看了一些velocity的資料,把所見所得做個(gè)簡(jiǎn)單不系統(tǒng)的筆記寫下來(lái),算是增強(qiáng)記憶。

    動(dòng)態(tài)語(yǔ)言的特性:

    動(dòng)態(tài)語(yǔ)言需要一個(gè)解釋器,而這個(gè)解釋器一般在服務(wù)器中。

    MVC

    Model:系統(tǒng)和應(yīng)用的狀態(tài)表示,一般是類或者其他數(shù)據(jù)結(jié)構(gòu)。可以改變系統(tǒng)狀態(tài)的Actionsmethod。典型的javabean。設(shè)計(jì)初衷就是為了數(shù)據(jù)和顯示的分離

    View:顯示結(jié)果數(shù)據(jù)的組成部分,隨著model的不同以及狀態(tài)改變,view也要相應(yīng)的做出變化。

    Controller:用戶和應(yīng)用之間交互的橋梁。Controller捕獲用戶的輸入,并利用既定邏輯決定將這些命令輸入路由到哪一個(gè)model進(jìn)行處理。

    只使用jsp技術(shù)叫做model 1

    加入servlet后叫做model 2

    什么是Velocity

    Velocity is a template language designed to give Web designers an easy way to

    present dynamic information to users of a Web site or application.

    Velocity有個(gè)集合叫做context,說(shuō)白了就是controllermodel層的封裝,提供了網(wǎng)頁(yè)模板。

    實(shí)現(xiàn)了velocity的代碼將利用從context中的對(duì)象里獲取的數(shù)據(jù)替換模板中的腳本元素。

    Velocity的使用簡(jiǎn)單代碼:

    一個(gè)簡(jiǎn)單的語(yǔ)言描述過(guò)程就是:將velocity初始化并在contextput進(jìn)去對(duì)象,然后template加載某個(gè)vm模板,然后用template將這個(gè)vmcontext進(jìn)行merge,就生成了view頁(yè)面了。

    Context可以把其他類型的數(shù)據(jù)put進(jìn)來(lái),velocity會(huì)自動(dòng)的調(diào)用這些對(duì)象的toString方法。

    下面重點(diǎn)說(shuō)說(shuō)context

    Context介紹

    Context本質(zhì)上是一個(gè)介于java代碼層和velocity模板層之間的一個(gè)數(shù)據(jù)橋梁。Java開發(fā)人員將各種各樣的數(shù)據(jù)對(duì)象放到context中,頁(yè)面模板設(shè)計(jì)人員從context取得這些對(duì)象的referenceVelocity中定義了VelocityContext來(lái)提供基本實(shí)現(xiàn)。這個(gè)實(shí)現(xiàn)與java中的hashtable類似,最有用和常用的方法就是

    Public Object put(String key, Object value);

    Public Object get(String key);

    如果理解了context的容器特性,那么什么東西能放進(jìn)去呢?context首先支持放一些迭代對(duì)象(Iterative Objects),比如對(duì)象數(shù)組Object[], java.util.Collection, java.util.Map, java.util.Iterator, java.util.Enumeration, 以及任意的有public Iterator iterator()方法的public class。其次context還支持put靜態(tài)類(static class),比如context.put(“Math”, Math.class)。當(dāng)然,在velocity運(yùn)行時(shí)模板 產(chǎn)生的對(duì)象也可以放到context中。

    Velocity的三種reference

    變量variable:對(duì)應(yīng)java對(duì)象的一種字符串化的表示,它返回的值是調(diào)用了javatoString方法后的結(jié)果。

    方法method:調(diào)用所引用對(duì)象的某個(gè)方法,該方法必須是public類的一個(gè)public方法。如果該方法有返回值,那么velocity在調(diào)用完方法后會(huì)同樣的對(duì)返回值進(jìn)行toString包裝。對(duì)參數(shù)的要求是velocity要求所有的方法參數(shù)也必須是string的。

    屬性property:類似方法,除了訪問java類的屬性外,還等價(jià)于get***方法。

    $!前綴是quiet notation符號(hào),用這個(gè)前綴產(chǎn)生的引用在引用對(duì)象不存在的時(shí)候,會(huì)返回“”字符串而不是不存在的對(duì)象的名字的字符串。

    "”是轉(zhuǎn)義字符,可以轉(zhuǎn)義$符號(hào)和其他符號(hào)

    Velocity指令

    #stop:用于debug,當(dāng)engine遇到這個(gè)指令,就會(huì)停止執(zhí)行,并將控制權(quán)返回給調(diào)用程序。

    #include:用于包含外部文件,將外部文件的內(nèi)容直接加入程序中。

    #parse:與include類似,但是不同之處在于,include引入的是靜態(tài)的文件,而parse會(huì)動(dòng)態(tài)的加載模板,也就是說(shuō),parse會(huì)解析vm文件,然后再加入到源文件中去。

    #set:就是一個(gè)很強(qiáng)大的賦值指令,不管被賦值的變量是否已經(jīng)存在或賦值,新的set指令會(huì)完全覆蓋。指令格式就是#set(ref=value)。幾個(gè)值得注意的set用法如下

    Listrange的用法可以等同的看做是java里的ArrayList

    對(duì)boolean值的setset支持短路short circuit,具體代碼見下:

    #end:聲明一個(gè)程序塊的結(jié)束,必須以#if或者#foreach或者#macro開始。

    #if:就是普通的if,只不過(guò)在#if中,條件表達(dá)式里用true表示真,用false表示假,沒有null表達(dá)式。測(cè)試null的話直接用#if($condition)指令即可。常用的邏輯操作符(&&||!)都可以使用,比較操作符也與java相同。

    #else:接著#if的使用指令,邏輯分支,同java等其他語(yǔ)言的邏輯一樣。有一點(diǎn)需要注意,沒有#else#if需要#end,有了#else,那么#end加在#else后即可,#if后不需要再加#end。如:

    #elseif:就是多分支情況下的else if合寫。對(duì)#end的要求同#else

    #foreach:直接用例子解釋:

    當(dāng)然需要補(bǔ)充一點(diǎn)的是,這個(gè)循環(huán)訪問的list的生成不僅可以在頁(yè)面中定義,如上例,也可以在context中產(chǎn)生,比如在put的時(shí)候就把javaarray或者實(shí)現(xiàn)了集合類的map,collectionput進(jìn)去。當(dāng)然,直接foreach一個(gè)map,那么就是訪問的mapvalue,想訪問它的key的話需要調(diào)用該mapkeySet方法得到setForeach的內(nèi)置循環(huán)增量叫做$velocityCount

    #macro:就是velocity里對(duì)于c語(yǔ)言中的宏的概念,注意不是函數(shù),功能雖然類似,但是macro是在運(yùn)行時(shí)之前就確定好的,因此用#parse解析無(wú)效。語(yǔ)法就是#macro(name $param1 $param2)這樣的樣式,其中name是宏的名字,后面的param是參數(shù)。調(diào)用時(shí)候的參數(shù)的個(gè)數(shù)一定要與聲明的匹配,velocity不提供默認(rèn)參數(shù)和重載實(shí)現(xiàn)。參數(shù)類型可以是字符串,數(shù)字常量,booleanrange操作符,數(shù)組列表和velocity引用。

    想定義一個(gè)全部vm通用的宏,那么要把它放在VM_global_library.vm里。

    Velocimacro properties

    Velocimacro.library:聲明組成velocimacro library的文件名。默認(rèn)是VM_global_library.vm

    Velocimacro.permissions.allow.inline:如果設(shè)置這個(gè)屬性為false,那么內(nèi)聯(lián)的macro聲明將不被引擎執(zhí)行。默認(rèn)是true的。

    Velocimacro.permissions.allow.inline.to.replace.global:聲明一個(gè)內(nèi)聯(lián)的macro是否可以override一個(gè)library提供的macro。默認(rèn)是false

    Velocimacro. permissions.allow.inline.local.scope:聲明模板是否可以提供私有的關(guān)于velocimacro的命名空間。一旦被設(shè)置為true,那么內(nèi)聯(lián)的macro只可以被本模板看到。默認(rèn)是false

    Velocimacro.context.localscope:聲明在使用velocimacro時(shí)#set指令所影響的velocitycontext的行為(好蹩腳)。就是說(shuō),一旦設(shè)置這個(gè)屬性為truevelocimacro只接受本地的context。調(diào)用者注入到context中的對(duì)象將不被看到。默認(rèn)是false

    Velocimacro.library.autoreload:聲明一個(gè)修改后的velocimacro library是否在macro被調(diào)用時(shí)自動(dòng)reload。默認(rèn)是false

    Velocimacro.messages.on:聲明是否由引擎產(chǎn)生額外的log信息,默認(rèn)是true

    遞歸和嵌套macro都是允許的,但是遞歸的方法是不推薦的。

    下面是講velocity是如何開始作用的:

    通過(guò)調(diào)用Velocity.init()這個(gè)靜態(tài)方法,我們初始化了runtime。這個(gè)調(diào)用的結(jié)果就是運(yùn)行時(shí)的引擎通過(guò)讀取org/apache/velocity/runtime/defaults/velocity.properties文件被初始化。Velocity提供了3種定制技術(shù)去定制runtime configuration

    第一種技術(shù):自定義一個(gè)properties文件,然后通過(guò)init的帶參數(shù)方法初始化velocity引擎。

    第二種技術(shù):在運(yùn)行時(shí)構(gòu)建一個(gè)javaProperties對(duì)象,然后通過(guò)set方法注入屬性,在程序代碼中傳遞給init參數(shù)。

    第三種技術(shù):為了更細(xì)粒度的控制velocity引擎的初始化,一些細(xì)節(jié)的實(shí)現(xiàn)就是可以利用velocity自己的一些靜態(tài)方法在init之前去修改屬性文件。比如Velocity.setProperty(String propertyName, String value)

    更多的屬性:

    Directive類的

    Directive.foreach.counter.name:聲明了foreach循環(huán)中的循環(huán)變量名字,默認(rèn)是velocityCount

    Directive.foreach.counter.initial.value:聲明了循環(huán)時(shí)循環(huán)變量的初始值,默認(rèn)是1,雖然C系語(yǔ)言的初始值都為0.

    Directive.include.output.errormsg.start:聲明了在include調(diào)用時(shí)輸入錯(cuò)誤參數(shù)所顯示的出錯(cuò)提示文本的開頭,默認(rèn)是“<!—include error:”。

    Directive.include.output.errormsg.end:同上,代表了結(jié)尾,默認(rèn)值是“see error log -->

    Directive.parse.max.depth:這個(gè)聲明了parse命令的最大嵌套深度。默認(rèn)是10.

    Encoding類的

    Input.encoding:聲明被模板引擎處理的模板的編碼,默認(rèn)是ISO-8859-1.

    Output.encoding:聲明關(guān)聯(lián)到輸出流的編碼,默認(rèn)是ISO-8859-1

    Logging類的

    Runtime.log:聲明velocitylog文件所在的路徑,默認(rèn)是velocity.log

    Runtime.log.logsystem:聲明velocitylog任務(wù)系統(tǒng),設(shè)置的值需要實(shí)現(xiàn)org.apache.velocity.runtime.log.LogSystem接口。無(wú)默認(rèn)值。

    Runtime.log.logsystem.class:聲明velocity運(yùn)行時(shí)用于處理logging服務(wù)的類名,包含一系列用逗號(hào)隔開的列表。默認(rèn)值是runtime.log.logsystem.class property is org.apache.velocity.

    runtime.log.AvalonLogSystem,org.apache.velocity.runtime.log.SimpleLog4J

    logSystem. Logging may be disabled by providing a value of org.apache.velocity.

    runtime.log.NullLogSystem

    runtime.log.error.stacktrace

    runtime.log.warn.stacktrace

    runtime.log.info.stacktrace:這三個(gè)分別用來(lái)聲明運(yùn)行時(shí)引擎在記錄錯(cuò)誤、警告和信息消息時(shí)是否開啟stacktrace。默認(rèn)值都是false

    Runtime.log.invalid.references:聲明非法引用在模板中發(fā)現(xiàn)時(shí)是否記錄的標(biāo)記,默認(rèn)是true

    Resource Management類的

    Resource.manager.class:聲明處理velocity資源管理任務(wù)的類,該類必須實(shí)現(xiàn)org.apache.velocity.runtime.resource.ResourceManager接口。默認(rèn)值是org.apache.velocity.runtime.resource.ResourceManagerImpl

    Resource.manager.cache.class:聲明了資源管理緩存請(qǐng)求的類,該類必須實(shí)現(xiàn)org.apache.velocity.runtime.resource.ResourceCache接口。默認(rèn)是org.apache.velocity.runtime.resource.ResourceCacheImpl

    Resource.manager.logwhenfound:聲明了資源管理在第一次定位資源時(shí)是否記錄log。默認(rèn)是true

    Resource.loader:關(guān)聯(lián)一個(gè)名字給指定的resource loader

    <loader>.resource.loader.description:聲明了resource loader的文字描述。

    <loader>.resource.loader.class:聲明了用于初始化加載關(guān)聯(lián)資源類型的類,該類需要繼承org.apache.velocity.runtime.resource.loader.ResourceLoader類,并且提供特定功能的資源類型。Velocity.properties提供了一個(gè)org.apache.velocity.runtime.resource.loader.FileResourceLoader的類。

    <loader>.resource.loader.path:聲明了一個(gè)根目錄用來(lái)存放相關(guān)類型的資源。Velocity.properties提供了.作為根目錄。

    <loader>.resource.loader.cache:聲明loader是否要緩存特定資源。一般建議true

    <loader>.resource.loader.modificationCheckInterval:聲明了檢查緩存資源是否有修改的時(shí)間間隔,以秒為單位。默認(rèn)是2.

    其他類的

    Runtime.initerpolate.string.literals:聲明了模板引擎是否要插入字符串常量,默認(rèn)是true

    Parser.pool.size:聲明了啟動(dòng)時(shí)runtime創(chuàng)建的parser pool的大小,默認(rèn)是20.

    Resource loaders資源加載

    一個(gè)velocityresource簡(jiǎn)單說(shuō)就是一個(gè)提供給模板引擎的輸入。包括正規(guī)模板、velocimacrolibrary、由include指令引入的普通文本。一個(gè)resource loader就是一個(gè)知道如何從這些特定的resource中提取資源的實(shí)體。一般用到的就是file resource loader,當(dāng)然velocity還提供了3種其他loader類型:JAR, ClasspathDataSource

    Events事件

    為了提供模板處理時(shí)的更好控制,velocity提供了事件處理等級(jí),支持用戶干預(yù)。

    有三種事件類型:

    第一,   #set指令中為引用賦NULL的時(shí)候。

    第二,   Java方法調(diào)用velocity方法或?qū)傩砸贸霈F(xiàn)異常的時(shí)候。

    第三,   每次velocity引用對(duì)應(yīng)的值插入輸出流的時(shí)候。

    Velocity提供了NullSetEventHandler, MethodExceptionEventHandlerReferenceInsertionEventHandler接口去處理這些事件。

    Context chaining

    簡(jiǎn)單講就是一層層的包裝context(直覺讓我想起façade模式),如果有重復(fù)的話,最外層的覆蓋最里層的,但是本層的context對(duì)于重復(fù)的key還是可以保持可訪問。實(shí)現(xiàn)方式是通過(guò)VelocityContext的重載構(gòu)造方法。

    VelocityXML

    velocity支持對(duì)xml的處理,只要加入類似這樣的代碼即可

    接著在displayxml.vm這樣寫:

    然后就可以咯。

    如何輸出XML與輸出HTML是一致的。

    結(jié)合velocityservlet

    其實(shí)很簡(jiǎn)單,寫一個(gè)類,繼承VelocityServlet。不需要普通的doGetdoPost方法,取而代之的是一個(gè)handleRequest方法,該方法傳遞3個(gè)參數(shù),HttpServletRequest, HttpServletResponseContext。前兩個(gè)參數(shù)與普通的servlet一樣,最后一個(gè)參數(shù)就對(duì)應(yīng)了velocity模板引擎的context。該方法返回一個(gè)Template。基礎(chǔ)代碼如下:

    HttpServletRequestHttpServletResponsecontext中同樣存在,名字分別是reqres,我們可以寫這樣的代碼去訪問和讀取requestresponse

    #set($username = $req.getParameter(‘username’))

    VelocityServlet非常強(qiáng)大,除了簡(jiǎn)單的handleRequest方法外,還包括了一系列方法:

    Properties loadConfiguration(ServletConfig):允許添加額外的servlet屬性。

    Context createContext(HttpServletRequest, HttpServletResponse):允許開發(fā)者創(chuàng)建自己的context,這個(gè)context可以進(jìn)行似有的merge

    void setContentType( HttpServletRequest,HttpServletResponse):設(shè)置內(nèi)容類型,默認(rèn)的是text/html格式。

    void mergeTemplate(Template, Context, HttpServletResponse):自行控制合并模板的方法,可以繞過(guò)handleRequest

    void requestCleanup(HttpServletRequest, HttpServletResponse,Context):自行合并后的清理操作。

    protected void error(HttpServletRequest, HttpServletResponse, Exception):錯(cuò)誤處理。

    Velocityturbine的結(jié)合

    可以說(shuō)turbinevelocity的最好舞臺(tái),它天然的結(jié)合了velocity

    Turbine的三個(gè)特性:

    1.       基于servlet作為控制器

    2.       強(qiáng)調(diào)安全繼承

    3.       獨(dú)立于web使用。

    TurbineMVC經(jīng)典組合就是EJB作為模型,servlet寫控制器,而velocity是顯示。

    先看看turbine的架構(gòu):

    5大模塊,都在assembler下面。其中

    Action:完成特定任務(wù)的代碼。

    Navigation:用來(lái)顯示導(dǎo)航鏈接和控制的velocity模板。

    Screenvelocity模板和java類的組合,用來(lái)顯示layout模塊內(nèi)的核心內(nèi)容。

    Layoutvelocity模板,用來(lái)描述頁(yè)面如何工作。

    Page:一個(gè)包含了所有這些模塊的概念級(jí)別的對(duì)象。

    先來(lái)看看action模塊:

    這個(gè)圖是action和其他模塊之間的一個(gè)流動(dòng)視圖。當(dāng)有一個(gè)get或者post請(qǐng)求時(shí),page模塊將執(zhí)行action模塊,由action模塊判斷由哪個(gè)screen來(lái)顯示信息。

    Navigation模塊:

    說(shuō)白了就是webx中的control,控制頁(yè)面的上下左右各個(gè)部分,表達(dá)不同的所謂navigation schemes。這個(gè)模塊是被layout執(zhí)行的。

    Screen模塊:

    Navigation模塊展示了頁(yè)面的各個(gè)邊緣組成,那么screen就負(fù)責(zé)顯示頁(yè)面的核心內(nèi)容。

    Layout模塊:

    Layout如其名,就是通過(guò)布局來(lái)控制哪里安排navigation,哪里顯示screen

    Page模塊:

    Page是整個(gè)web應(yīng)用的外殼,請(qǐng)求也是先到達(dá)page的。Page更像一個(gè)容器,用來(lái)管理和聯(lián)系整個(gè)的各個(gè)模塊。


    這個(gè)圖顯示了各個(gè)模塊的包裝關(guān)系。

    Turbine定義了5個(gè)loader去加載這5個(gè)模塊,loader的結(jié)構(gòu)圖如下:


    未完待續(xù)~~

    參考資料:

    http://velocity.apache.org/里的user guidedeveloper guide

    Wiley - Mastering Apache Velocity》,Joseph D. Gradecki, Jim Cole

    posted on 2011-04-07 11:03 changedi 閱讀(10033) 評(píng)論(1)  編輯  收藏 所屬分類: Java技術(shù)

    評(píng)論

    # re: velocity學(xué)習(xí)筆記(上) 2013-07-26 17:42 VAllen

    只能說(shuō)Java版的Velocity太棒了。
    而.NET版的NVelocity依然有很多不足之處。
    其次context還支持put靜態(tài)類(static class),比如context.put(“Math”, Math.class)..
    我想put一個(gè)靜態(tài)類都做不到,杯具~~
    如有解決方案,請(qǐng)電郵caizz@vip.qq.com,感激不盡~  回復(fù)  更多評(píng)論   

    主站蜘蛛池模板: 好先生在线观看免费播放| 亚洲欧洲av综合色无码| 日产国产精品亚洲系列| 免费精品国产自产拍在| 黄页免费在线观看 | 亚洲av无码片vr一区二区三区| 日韩va亚洲va欧洲va国产| 亚洲国产a级视频| 好吊妞788免费视频播放| 亚洲免费观看在线视频| 野花香高清视频在线观看免费 | **俄罗斯毛片免费| 免费国产在线视频| 精品国产污污免费网站入口| 亚洲精品乱码久久久久蜜桃| 亚洲AV无码乱码在线观看代蜜桃| 久久久久亚洲AV无码麻豆| 亚洲成色在线综合网站| 久久久久亚洲av成人无码电影 | 亚洲Av永久无码精品黑人| tom影院亚洲国产一区二区| 亚洲一二成人精品区| 亚洲av日韩av无码黑人| 亚洲AV永久无码精品水牛影视| 亚洲女人被黑人巨大进入| 国产hs免费高清在线观看| 男女交性永久免费视频播放| 岛国av无码免费无禁网站| 日本在线高清免费爱做网站| 免费看片在线观看| 97性无码区免费| 成人免费一级毛片在线播放视频| 最近的中文字幕大全免费8| 最近免费中文字幕大全高清大全1 最近免费中文字幕mv在线电影 | 国产成人精品日本亚洲18图| 91亚洲精品自在在线观看| 亚洲黄色网站视频| 亚洲国产成人久久精品app| 亚洲免费人成视频观看| 亚洲人成色在线观看| jzzijzzij在线观看亚洲熟妇|