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

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

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

    Change Dir

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

    統計

    留言簿(18)

    積分與排名

    “牛”們的博客

    各個公司技術

    我的鏈接

    淘寶技術

    閱讀排行榜

    評論排行榜

    velocity學習筆記(上)

     

    Velocity筆記(上)

    雜七雜八的看了一些velocity的資料,把所見所得做個簡單不系統的筆記寫下來,算是增強記憶。

    動態語言的特性:

    動態語言需要一個解釋器,而這個解釋器一般在服務器中。

    MVC

    Model:系統和應用的狀態表示,一般是類或者其他數據結構。可以改變系統狀態的Actionsmethod。典型的javabean。設計初衷就是為了數據和顯示的分離

    View:顯示結果數據的組成部分,隨著model的不同以及狀態改變,view也要相應的做出變化。

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

    只使用jsp技術叫做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有個集合叫做context,說白了就是controllermodel層的封裝,提供了網頁模板。

    實現了velocity的代碼將利用從context中的對象里獲取的數據替換模板中的腳本元素。

    Velocity的使用簡單代碼:

    一個簡單的語言描述過程就是:將velocity初始化并在contextput進去對象,然后template加載某個vm模板,然后用template將這個vmcontext進行merge,就生成了view頁面了。

    Context可以把其他類型的數據put進來,velocity會自動的調用這些對象的toString方法。

    下面重點說說context

    Context介紹

    Context本質上是一個介于java代碼層和velocity模板層之間的一個數據橋梁。Java開發人員將各種各樣的數據對象放到context中,頁面模板設計人員從context取得這些對象的referenceVelocity中定義了VelocityContext來提供基本實現。這個實現與java中的hashtable類似,最有用和常用的方法就是

    Public Object put(String key, Object value);

    Public Object get(String key);

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

    Velocity的三種reference

    變量variable:對應java對象的一種字符串化的表示,它返回的值是調用了javatoString方法后的結果。

    方法method:調用所引用對象的某個方法,該方法必須是public類的一個public方法。如果該方法有返回值,那么velocity在調用完方法后會同樣的對返回值進行toString包裝。對參數的要求是velocity要求所有的方法參數也必須是string的。

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

    $!前綴是quiet notation符號,用這個前綴產生的引用在引用對象不存在的時候,會返回“”字符串而不是不存在的對象的名字的字符串。

    "”是轉義字符,可以轉義$符號和其他符號

    Velocity指令

    #stop:用于debug,當engine遇到這個指令,就會停止執行,并將控制權返回給調用程序。

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

    #parse:與include類似,但是不同之處在于,include引入的是靜態的文件,而parse會動態的加載模板,也就是說,parse會解析vm文件,然后再加入到源文件中去。

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

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

    boolean值的setset支持短路short circuit,具體代碼見下:

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

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

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

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

    #foreach:直接用例子解釋:

    當然需要補充一點的是,這個循環訪問的list的生成不僅可以在頁面中定義,如上例,也可以在context中產生,比如在put的時候就把javaarray或者實現了集合類的map,collectionput進去。當然,直接foreach一個map,那么就是訪問的mapvalue,想訪問它的key的話需要調用該mapkeySet方法得到setForeach的內置循環增量叫做$velocityCount

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

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

    Velocimacro properties

    Velocimacro.library:聲明組成velocimacro library的文件名。默認是VM_global_library.vm

    Velocimacro.permissions.allow.inline:如果設置這個屬性為false,那么內聯的macro聲明將不被引擎執行。默認是true的。

    Velocimacro.permissions.allow.inline.to.replace.global:聲明一個內聯的macro是否可以override一個library提供的macro。默認是false

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

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

    Velocimacro.library.autoreload:聲明一個修改后的velocimacro library是否在macro被調用時自動reload。默認是false

    Velocimacro.messages.on:聲明是否由引擎產生額外的log信息,默認是true

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

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

    通過調用Velocity.init()這個靜態方法,我們初始化了runtime。這個調用的結果就是運行時的引擎通過讀取org/apache/velocity/runtime/defaults/velocity.properties文件被初始化。Velocity提供了3種定制技術去定制runtime configuration

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

    第二種技術:在運行時構建一個javaProperties對象,然后通過set方法注入屬性,在程序代碼中傳遞給init參數。

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

    更多的屬性:

    Directive類的

    Directive.foreach.counter.name:聲明了foreach循環中的循環變量名字,默認是velocityCount

    Directive.foreach.counter.initial.value:聲明了循環時循環變量的初始值,默認是1,雖然C系語言的初始值都為0.

    Directive.include.output.errormsg.start:聲明了在include調用時輸入錯誤參數所顯示的出錯提示文本的開頭,默認是“<!—include error:”。

    Directive.include.output.errormsg.end:同上,代表了結尾,默認值是“see error log -->

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

    Encoding類的

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

    Output.encoding:聲明關聯到輸出流的編碼,默認是ISO-8859-1

    Logging類的

    Runtime.log:聲明velocitylog文件所在的路徑,默認是velocity.log

    Runtime.log.logsystem:聲明velocitylog任務系統,設置的值需要實現org.apache.velocity.runtime.log.LogSystem接口。無默認值。

    Runtime.log.logsystem.class:聲明velocity運行時用于處理logging服務的類名,包含一系列用逗號隔開的列表。默認值是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:這三個分別用來聲明運行時引擎在記錄錯誤、警告和信息消息時是否開啟stacktrace。默認值都是false

    Runtime.log.invalid.references:聲明非法引用在模板中發現時是否記錄的標記,默認是true

    Resource Management類的

    Resource.manager.class:聲明處理velocity資源管理任務的類,該類必須實現org.apache.velocity.runtime.resource.ResourceManager接口。默認值是org.apache.velocity.runtime.resource.ResourceManagerImpl

    Resource.manager.cache.class:聲明了資源管理緩存請求的類,該類必須實現org.apache.velocity.runtime.resource.ResourceCache接口。默認是org.apache.velocity.runtime.resource.ResourceCacheImpl

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

    Resource.loader:關聯一個名字給指定的resource loader

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

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

    <loader>.resource.loader.path:聲明了一個根目錄用來存放相關類型的資源。Velocity.properties提供了.作為根目錄。

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

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

    其他類的

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

    Parser.pool.size:聲明了啟動時runtime創建的parser pool的大小,默認是20.

    Resource loaders資源加載

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

    Events事件

    為了提供模板處理時的更好控制,velocity提供了事件處理等級,支持用戶干預。

    有三種事件類型:

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

    第二,   Java方法調用velocity方法或屬性引用出現異常的時候。

    第三,   每次velocity引用對應的值插入輸出流的時候。

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

    Context chaining

    簡單講就是一層層的包裝context(直覺讓我想起façade模式),如果有重復的話,最外層的覆蓋最里層的,但是本層的context對于重復的key還是可以保持可訪問。實現方式是通過VelocityContext的重載構造方法。

    VelocityXML

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

    接著在displayxml.vm這樣寫:

    然后就可以咯。

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

    結合velocityservlet

    其實很簡單,寫一個類,繼承VelocityServlet。不需要普通的doGetdoPost方法,取而代之的是一個handleRequest方法,該方法傳遞3個參數,HttpServletRequest, HttpServletResponseContext。前兩個參數與普通的servlet一樣,最后一個參數就對應了velocity模板引擎的context。該方法返回一個Template。基礎代碼如下:

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

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

    VelocityServlet非常強大,除了簡單的handleRequest方法外,還包括了一系列方法:

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

    Context createContext(HttpServletRequest, HttpServletResponse):允許開發者創建自己的context,這個context可以進行似有的merge

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

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

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

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

    Velocityturbine的結合

    可以說turbinevelocity的最好舞臺,它天然的結合了velocity

    Turbine的三個特性:

    1.       基于servlet作為控制器

    2.       強調安全繼承

    3.       獨立于web使用。

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

    先看看turbine的架構:

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

    Action:完成特定任務的代碼。

    Navigation:用來顯示導航鏈接和控制的velocity模板。

    Screenvelocity模板和java類的組合,用來顯示layout模塊內的核心內容。

    Layoutvelocity模板,用來描述頁面如何工作。

    Page:一個包含了所有這些模塊的概念級別的對象。

    先來看看action模塊:

    這個圖是action和其他模塊之間的一個流動視圖。當有一個get或者post請求時,page模塊將執行action模塊,由action模塊判斷由哪個screen來顯示信息。

    Navigation模塊:

    說白了就是webx中的control,控制頁面的上下左右各個部分,表達不同的所謂navigation schemes。這個模塊是被layout執行的。

    Screen模塊:

    Navigation模塊展示了頁面的各個邊緣組成,那么screen就負責顯示頁面的核心內容。

    Layout模塊:

    Layout如其名,就是通過布局來控制哪里安排navigation,哪里顯示screen

    Page模塊:

    Page是整個web應用的外殼,請求也是先到達page的。Page更像一個容器,用來管理和聯系整個的各個模塊。


    這個圖顯示了各個模塊的包裝關系。

    Turbine定義了5loader去加載這5個模塊,loader的結構圖如下:


    未完待續~~

    參考資料:

    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) 評論(1)  編輯  收藏 所屬分類: Java技術

    評論

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

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

    主站蜘蛛池模板: 亚洲一区二区无码偷拍| 黄页网站在线观看免费| 新最免费影视大全在线播放| 毛片在线全部免费观看| 天天摸天天碰成人免费视频| 亚洲无码在线播放| 亚洲欧洲日本在线观看| 成人一区二区免费视频| 好吊妞视频免费视频| 久久精品国产亚洲av麻豆| 久久无码av亚洲精品色午夜| 最好看的中文字幕2019免费| 亚洲av麻豆aⅴ无码电影| 亚洲国产精品久久网午夜| 国产免费人成视频在线播放播| 免费做爰猛烈吃奶摸视频在线观看 | 成年女人18级毛片毛片免费观看| 亚洲情综合五月天| 亚洲AV无码AV吞精久久| 51视频精品全部免费最新| 久久夜色精品国产亚洲av| 亚洲精品第一国产综合亚AV| 99精品热线在线观看免费视频| 免费成人黄色大片| 亚洲一区二区三区高清不卡| 在线毛片片免费观看| 亚洲国产精品成人久久蜜臀| 最新亚洲春色Av无码专区| 免费看又黄又无码的网站| 亚洲天堂免费在线视频| 亚洲精品永久在线观看| 日本视频一区在线观看免费| 亚洲韩国精品无码一区二区三区| 激情小说亚洲图片| 我想看一级毛片免费的| 亚洲精品国产电影午夜| 你懂的免费在线观看网站| 中文字幕亚洲无线码| 免费一区二区无码视频在线播放 | 亚洲女子高潮不断爆白浆| 亚洲电影免费观看|