176142998

            BlogJava :: 首頁(yè) :: 聯(lián)系 :: 聚合  :: 管理
            116 Posts :: 0 Stories :: 45 Comments :: 0 Trackbacks

          #

          (1)模板 + 數(shù)據(jù)模型 = 輸出

          FreeMarker基于設(shè)計(jì)者和程序員是具有不同專業(yè)技能的不同個(gè)體的觀念他們是分工勞動(dòng)的:
          設(shè)計(jì)者專注于表示——?jiǎng)?chuàng)建HTML文件、圖片、Web頁(yè)面的其它可視化方面;
          程序員創(chuàng)建系統(tǒng),生成設(shè)計(jì)頁(yè)面要顯示的數(shù)據(jù)。
          經(jīng)常會(huì)遇到的問(wèn)題是:在Web頁(yè)面(或其它類型的文檔)中顯示的信息在設(shè)計(jì)頁(yè)面時(shí)是無(wú)效的,是基于動(dòng)態(tài)數(shù)據(jù)的。在這里,你可以在HTML(或其它要輸出的文本)中加入一些特定指令,F(xiàn)reeMarker會(huì)在輸出頁(yè)面給最終用戶時(shí),用適當(dāng)?shù)臄?shù)據(jù)替代這些代碼。

          下面是一個(gè)例子:

          <html>
          <head>
          <title>Welcome!</title>
          </head>
          <body>
          <h1>Welcome ${user}!</h1>
          <p>Our latest product:
          <a href="${latestProduct.url}">${latestProduct.name}</a>!
          </body>
          </html>
          
          這個(gè)例子是在簡(jiǎn)單的HTML中加入了一些由${…}包圍的特定代碼,這些特定代碼是FreeMarker的指令,而包含F(xiàn)reeMarker的指令的文件就稱為模板(Template)。
          至于user、latestProduct.url和latestProduct.name來(lái)自于數(shù)據(jù)模型(data model)。
          數(shù)據(jù)模型由程序員編程來(lái)創(chuàng)建,向模板提供變化的信息,這些信息來(lái)自于數(shù)據(jù)庫(kù)、文件,甚至于在程序中直接生成。
          模板設(shè)計(jì)者不關(guān)心數(shù)據(jù)從那兒來(lái),只知道使用已經(jīng)建立的數(shù)據(jù)模型。

          下面是一個(gè)可能的數(shù)據(jù)模型:

          (root)
          |
          +- user = "Big Joe"
          |
          +- latestProduct
          |
          +- url = "products/greenmouse.html"
          |
          +- name = "green mouse"
          
          數(shù)據(jù)模型類似于計(jì)算機(jī)的文件系統(tǒng),latestProduct可以看作是目錄。

          2、數(shù)據(jù)模型

          (1)基礎(chǔ)

          在快速入門(mén)中介紹了在模板中使用的三種基本對(duì)象類型:scalars、hashes 和sequences,其實(shí)還可以有其它更多的能力:

          • scalars:存儲(chǔ)單值
          • hashes:充當(dāng)其它對(duì)象的容器,每個(gè)都關(guān)聯(lián)一個(gè)唯一的查詢名字
          • sequences:充當(dāng)其它對(duì)象的容器,按次序訪問(wèn)
          • 方法:通過(guò)傳遞的參數(shù)進(jìn)行計(jì)算,以新對(duì)象返回結(jié)果
          • 用戶自定義FTL標(biāo)記:宏和變換器

          通常每個(gè)變量只具有上述的一種能力,但一個(gè)變量可以具有多個(gè)上述能力,如下面的例子:

          (root)
          |
          +- mouse = "Yerri"
          |
          +- age = 12
          |
          +- color = "brown">
          
          mouse既是scalars又是hashes,將上面的數(shù)據(jù)模型合并到下面的模板:
          ${mouse}       <#-- use mouse as scalar -->
          ${mouse.age}   <#-- use mouse as hash -->
          ${mouse.color} <#-- use mouse as hash -->
          
          輸出結(jié)果是:
          Yerri
          12
          brown
          

          (2)Scalar變量

          Scalar變量存儲(chǔ)單值,可以是:

          • 字符串:簡(jiǎn)單文本,在模板中使用引號(hào)(單引號(hào)或雙引號(hào))括起
          • 數(shù)字:在模板中直接使用數(shù)字值
          • 日期:存儲(chǔ)日期/時(shí)間相關(guān)的數(shù)據(jù),可以是日期、時(shí)間或日期-時(shí)間(Timestamp);通常情況,日期值由程序員加到數(shù)據(jù)模型中,設(shè)計(jì)者只需要顯示它們
          • 布爾值:true或false,通常在<#if …>標(biāo)記中使用

          (3)hashes 、sequences和集合

          有些變量不包含任何可顯示的內(nèi)容,而是作為容器包含其它變量,者有兩種類型:

          • hashes:具有一個(gè)唯一的查詢名字和它包含的每個(gè)變量相關(guān)聯(lián)
          • sequences:使用數(shù)字和它包含的每個(gè)變量相關(guān)聯(lián),索引值從0開(kāi)始

          集合變量通常類似sequences,除非無(wú)法訪問(wèn)它的大小和不能使用索引來(lái)獲得它的子變量;集合可以看作只能由<#list …>指令使用的受限sequences

          (4)方法

          方法變量通常是基于給出的參數(shù)計(jì)算值。

          下面的例子假設(shè)程序員已經(jīng)將方法變量avg放到數(shù)據(jù)模型中,用來(lái)計(jì)算數(shù)字平均值:

          The average of 3 and 5 is: ${avg(3, 5)}
          The average of 6 and 10 and 20 is: ${avg(6, 10, 20)}
          The average of the price of python and elephant is:
          ${avg(animals.python.price, animals.elephant.price)}
          

          (5)宏和變換器

          宏和變換器變量是用戶自定義指令(自定義FTL標(biāo)記),會(huì)在后面講述這些高級(jí)特性

          (6)節(jié)點(diǎn)

          節(jié)點(diǎn)變量表示為樹(shù)型結(jié)構(gòu)中的一個(gè)節(jié)點(diǎn),通常在XML處理中使用,會(huì)在后面的專門(mén)章節(jié)中講

          3、模板

          (1)整體結(jié)構(gòu)

          模板使用FTL(FreeMarker模板語(yǔ)言)編寫(xiě),是下面各部分的一個(gè)組合:

          • 文本:直接輸出
          • Interpolation:由${和},或#{和}來(lái)限定,計(jì)算值替代輸出
          • FTL標(biāo)記:FreeMarker指令,和HTML標(biāo)記類似,名字前加#予以區(qū)分,不會(huì)輸出
          • 注釋:由<#--和-->限定,不會(huì)輸出

          下面是以一個(gè)具體模板例子:

          <html>
          <head>
          <title>Welcome!</title>
          </head>
          <body>
          <#-- Greet the user with his/her name -->
          <h1>Welcome ${user}!</h1>
          <p>We have these animals:
          <ul>
          <#list animals as being>
          <li>${being.name} for ${being.price} Euros
          </#list>
          </ul>
          </body>
          </html>
          

          注意事項(xiàng):

          • FTL區(qū)分大小寫(xiě),所以list是正確的FTL指令,而List不是;${name}和${NAME}是不同的
          • Interpolation只能在文本中使用
          • FTL標(biāo)記不能位于另一個(gè)FTL標(biāo)記內(nèi)部,例如:
          <#if <#include 'foo'>='bar'>...</if>
          
          • 注釋可以位于FTL標(biāo)記和Interpolation內(nèi)部,如下面的例子:
          <h1>Welcome ${user <#-- The name of user -->}!</h1>
          <p>We have these animals:
          <ul>
          <#list <#-- some comment... --> animals as <#-- again... --> being>
          ...
          
          • 余的空白字符會(huì)在模板輸出時(shí)移除

          (2)指令

          在FreeMarker中,使用FTL標(biāo)記引用指令。有三種FTL標(biāo)記,這和HTML標(biāo)記是類似的:

          • 開(kāi)始標(biāo)記:<#directivename parameters>
          • 結(jié)束標(biāo)記:</#directivename>
          • 空內(nèi)容指令標(biāo)記:<#directivename parameters/>

          有兩種類型的指令:預(yù)定義指令和用戶定義指令。

          用戶定義指令要使用@替換#,如<@mydirective>...</@mydirective>(會(huì)在后面講述)。

          FTL標(biāo)記不能夠交叉,而應(yīng)該正確的嵌套,如下面的代碼是錯(cuò)誤的:

          <ul>
          <#list animals as being>
          <li>${being.name} for ${being.price} Euros
          <#if use = "Big Joe">
          (except for you)
          </#list>
          </#if> <#-- WRONG! -->
          </ul>
          
          如果使用不存在的指令,F(xiàn)reeMarker不會(huì)使用模板輸出,而是產(chǎn)生一個(gè)錯(cuò)誤消息。

          FreeMarker會(huì)忽略FTL標(biāo)記中的空白字符,如下面的例子:

          <#list
          animals       as
          being
          >
          ${being.name} for ${being.price} Euros
          </#list    >
          
          但是,<、</和指令之間不允許有空白字符。

          (3)表達(dá)式

          直接指定值

          • 字符串
          使用單引號(hào)或雙引號(hào)限定

          如果包含特殊字符需要轉(zhuǎn)義,如下面的例子:

          ${"It's \"quoted\" and
          this is a backslash: \\"}
          ${'It\'s "quoted" and
          this is a backslash: \\'}
          
          輸出結(jié)果是:
          It's "quoted" and
          this is a backslash: \
          It's "quoted" and
          this is a backslash: \
          
          下面是支持的轉(zhuǎn)義序列:

          轉(zhuǎn)義序列 含義
          \" 雙引號(hào)(u0022)
          \' 單引號(hào)(u0027)

          反斜杠(u005C)
          \n 換行(u000A)
          \r Return (u000D)
          \t Tab (u0009)
          \b Backspace (u0008)
          \f Form feed (u000C)
          \l <
          \g >
          \a &
          \{ {
          \xCode 4位16進(jìn)制Unicode代碼

          有一類特殊的字符串稱為raw字符串,被認(rèn)為是純文本,其中的\和{等不具有特殊含義,該類字符串在引號(hào)前面加r,下面是一個(gè)例子:

          ${r"${foo}"}
          ${r"C:\foo\bar"}
          
          輸出的結(jié)果是:
          ${foo}
          C:\foo\bar
          
          • 數(shù)字

          直接輸入,不需要引號(hào)

          精度數(shù)字使用“.”分隔,不能使用分組符號(hào)

          目前版本不支持科學(xué)計(jì)數(shù)法,所以“1E3”是錯(cuò)誤的

          不能省略小數(shù)點(diǎn)前面的0,所以“.5”是錯(cuò)誤的

          數(shù)字8、+8、08和8.00都是相同的

          • 布爾值

          true和false,不使用引號(hào)

          • 序列

          由逗號(hào)分隔的子變量列表,由方括號(hào)限定,下面是一個(gè)例子:

          <#list ["winter", "spring", "summer", "autumn"] as x>
          ${x}
          </#list>
          
          輸出的結(jié)果是:
          winter
          spring
          summer
          autumn
          
          列表的項(xiàng)目是表達(dá)式,所以可以有下面的例子:
          [2 + 2, [1, 2, 3, 4], "whatnot"]
          
          可以使用數(shù)字范圍定義數(shù)字序列,例如2..5等同于[2, 3, 4, 5],但是更有效率,注意數(shù)字范圍沒(méi)有方括號(hào)

          可以定義反遞增的數(shù)字范圍,如5..2

          • 散列(hash)
          由逗號(hào)分隔的鍵/值列表,由大括號(hào)限定,鍵和值之間用冒號(hào)分隔,下面是一個(gè)例子:
          {"name":"green mouse", "price":150}
          
          鍵和值都是表達(dá)式,但是鍵必須是字符串

          獲取變量

          • 頂層變量: ${variable},變量名只能是字母、數(shù)字、下劃線、$、@和#的組合,且不能以數(shù)字開(kāi)頭
          • 從散列中獲取數(shù)據(jù)

          可以使用點(diǎn)語(yǔ)法或方括號(hào)語(yǔ)法,假設(shè)有下面的數(shù)據(jù)模型:

          (root)
          |
          +- book
          |   |
          |   +- title = "Breeding green mouses"
          |   |
          |   +- author
          |       |
          |       +- name = "Julia Smith"
          |       |
          |       +- info = "Biologist, 1923-1985, Canada"
          |
          +- test = "title"
          
          下面都是等價(jià)的:
          book.author.name
          book["author"].name
          book.author.["name"]
          book["author"]["name"]
          
          使用點(diǎn)語(yǔ)法,變量名字有頂層變量一樣的限制,但方括號(hào)語(yǔ)法沒(méi)有該限制,因?yàn)槊质侨我獗磉_(dá)式的結(jié)果
          • 從序列獲得數(shù)據(jù):和散列的方括號(hào)語(yǔ)法語(yǔ)法一樣,只是方括號(hào)中的表達(dá)式值必須是數(shù)字;注意:第一個(gè)項(xiàng)目的索引是0

          序列片斷:使用[startIndex..endIndex]語(yǔ)法,從序列中獲得序列片斷(也是序列);startIndex和endIndex是結(jié)果為數(shù)字的表達(dá)式

          • 特殊變量:FreeMarker內(nèi)定義變量,使用.variablename語(yǔ)法訪問(wèn)

          字符串操作

          • Interpolation(或連接操作)

          可以使用${..}(或#{..})在文本部分插入表達(dá)式的值,例如:

          ${"Hello ${user}!"}
          ${"${user}${user}${user}${user}"}
          
          可以使用+操作符獲得同樣的結(jié)果
          ${"Hello " + user + "!"}
          ${user + user + user + user}
          
          ${..}只能用于文本部分,下面的代碼是錯(cuò)誤的:
          <#if ${isBig}>Wow!</#if>
          <#if "${isBig}">Wow!</#if>
          
          應(yīng)該寫(xiě)成:
          <#if isBig>Wow!</#if>
          
          • 子串

          例子(假設(shè)user的值為“Big Joe”):

          ${user[0]}${user[4]}
          ${user[1..4]}
          
          結(jié)果是(注意第一個(gè)字符的索引是0):
          BJ
          ig J
          
          序列操作
          • 連接操作:和字符串一樣,使用+,下面是一個(gè)例子:
          <#list ["Joe", "Fred"] + ["Julia", "Kate"] as user>
          - ${user}
          </#list>
          
          輸出結(jié)果是:
          - Joe
          - Fred
          - Julia
          - Kate
          
          散列操作
          • 連接操作:和字符串一樣,使用+,如果具有相同的key,右邊的值替代左邊的值,例如:
          <#assign ages = {"Joe":23, "Fred":25} + {"Joe":30, "Julia":18}>
          - Joe is ${ages.Joe}
          - Fred is ${ages.Fred}
          - Julia is ${ages.Julia}
          
          輸出結(jié)果是:
          - Joe is 30
          - Fred is 25
          - Julia is 18
          
          算術(shù)運(yùn)算
          • +、-、×、/、%,下面是一個(gè)例子:
          ${x * x - 100}
          ${x / 2}
          ${12 % 10}
          
          輸出結(jié)果是(假設(shè)x為5):
          -75
          2.5
          2
          
          操作符兩邊必須是數(shù)字,因此下面的代碼是錯(cuò)誤的:
          ${3 * "5"} <#-- WRONG! -->
          
          使用+操作符時(shí),如果一邊是數(shù)字,一邊是字符串,就會(huì)自動(dòng)將數(shù)字轉(zhuǎn)換為字符串,例如:
          ${3 + "5"}
          
          輸出結(jié)果是:
          35
          
          使用內(nèi)建的int(后面講述)獲得整數(shù)部分,例如:
          ${(x/2)?int}
          ${1.1?int}
          ${1.999?int}
          ${-1.1?int}
          ${-1.999?int}
          
          輸出結(jié)果是(假設(shè)x為5):
          2
          1
          1
          -1
          -1
          
          • 比較操作符

          使用=(或==,完全相等)測(cè)試兩個(gè)值是否相等,使用!= 測(cè)試兩個(gè)值是否不相等

          =和!=兩邊必須是相同類型的值,否則會(huì)產(chǎn)生錯(cuò)誤,例如<#if 1 = "1">會(huì)引起錯(cuò)誤

          Freemarker是精確比較,所以對(duì)"x"、"x "和"X"是不相等的

          對(duì)數(shù)字和日期可以使用<、<=、>和>=,但不能用于字符串

          由于Freemarker會(huì)將>解釋成FTL標(biāo)記的結(jié)束字符,所以對(duì)于>和>=可以使用括號(hào)來(lái)避免這種情況,例如<#if (x > y)>

          另一種替代的方法是,使用lt、lte、gt和gte來(lái)替代<、<=、>和>=

          • 邏輯操作符

          &&(and)、||(or)、!(not),只能用于布爾值,否則會(huì)產(chǎn)生錯(cuò)誤

          例子:

          <#if x < 12 && color = "green">
          We have less than 12 things, and they are green.
          </#if>
          <#if !hot> <#-- here hot must be a boolean -->
          It's not hot.
          </#if>
          
          • 內(nèi)建函數(shù)

          內(nèi)建函數(shù)的用法類似訪問(wèn)散列的子變量,只是使用“?”替代“.”,下面列出常用的一些函數(shù)

            • 字符串使用的:

          html:對(duì)字符串進(jìn)行HTML編碼

          cap_first:使字符串第一個(gè)字母大寫(xiě)

          lower_case:將字符串轉(zhuǎn)換成小寫(xiě)

          upper_case:將字符串轉(zhuǎn)換成大寫(xiě)

          trim:去掉字符串前后的空白字符

            • 序列使用的:

          size:獲得序列中元素的數(shù)目

            • 數(shù)字使用的:

          int:取得數(shù)字的整數(shù)部分(如-1.9?int的結(jié)果是-1)

          例子(假設(shè)test保存字符串"Tom & Jerry"):

          ${test?html}
          ${test?upper_case?html}
          
          輸出結(jié)果是:
          Tom &amp; Jerry
          TOM &amp; JERRY
          
          • 操作符優(yōu)先順序

          操作符組 操作符
          后綴 [subvarName] [subStringRange] . (methodParams)
          一元 +expr、-expr、!
          內(nèi)建 ?
          乘法 *、 / 、%
          加法 +、-
          關(guān)系 <、>、<=、>=(lt、lte、gt、gte)
          相等 ==(=)、!=
          邏輯and &&
          邏輯or 雙豎線
          數(shù)字范圍 ..

          (4)Interpolation

          Interpolation有兩種類型:

          1. 通用Interpolation:${expr}
          1. 數(shù)字Interpolation:#{expr}或#{expr; format}

          注意:Interpolation只能用于文本部分

          • 通用Interpolation

          插入字符串值:直接輸出表達(dá)式結(jié)果

          插入數(shù)字值:根據(jù)缺省格式(由#setting指令設(shè)置)將表達(dá)式結(jié)果轉(zhuǎn)換成文本輸出;可以使用內(nèi)建函數(shù)string格式化單個(gè)Interpolation,下面是一個(gè)例子:

          <#setting number_format="currency"/>
          <#assign answer=42/>
          ${answer}
          ${answer?string}  <#-- the same as ${answer} -->
          ${answer?string.number}
          ${answer?string.currency}
          ${answer?string.percent}
          
          輸出結(jié)果是:
          $42.00
          $42.00
          42
          $42.00
          4,200%
          
          插入日期值:根據(jù)缺省格式(由#setting指令設(shè)置)將表達(dá)式結(jié)果轉(zhuǎn)換成文本輸出;可以使用內(nèi)建函數(shù)string格式化單個(gè)Interpolation,下面是一個(gè)使用格式模式的例子:
          ${lastUpdated?string("yyyy-MM-dd HH:mm:ss zzzz")}
          ${lastUpdated?string("EEE, MMM d, ''yy")}
          ${lastUpdated?string("EEEE, MMMM dd, yyyy, hh:mm:ss a '('zzz')'")}
          
          輸出的結(jié)果類似下面的格式:
          2003-04-08 21:24:44 Pacific Daylight Time
          Tue, Apr 8, '03
          Tuesday, April 08, 2003, 09:24:44 PM (PDT)
          
          插入布爾值:根據(jù)缺省格式(由#setting指令設(shè)置)將表達(dá)式結(jié)果轉(zhuǎn)換成文本輸出;可以使用內(nèi)建函數(shù)string格式化單個(gè)Interpolation,下面是一個(gè)例子:
          <#assign foo=true/>
          ${foo?string("yes", "no")}
          
          輸出結(jié)果是:
          yes
          
          • 數(shù)字Interpolation的#{expr; format}形式可以用來(lái)格式化數(shù)字,format可以是:

          mX:小數(shù)部分最小X位

          MX:小數(shù)部分最大X位

          例子:

          <#-- If the language is US English the output is: -->
          <#assign x=2.582/>
          <#assign y=4/>
          #{x; M2}   <#-- 2.58 -->
          #{y; M2}   <#-- 4    -->
          #{x; m1}   <#-- 2.6 -->
          #{y; m1}   <#-- 4.0 -->
          #{x; m1M2} <#-- 2.58 -->
          #{y; m1M2} <#-- 4.0  -->
          

          4、雜項(xiàng)

          (1)用戶定義指令

          宏和變換器變量是兩種不同類型的用戶定義指令,它們之間的區(qū)別是宏是在模板中使用macro指令定義,而變換器是在模板外由程序定義,這里只介紹宏

          • 基本用法

          宏是和某個(gè)變量關(guān)聯(lián)的模板片斷,以便在模板中通過(guò)用戶定義指令使用該變量,下面是一個(gè)例子:

          <#macro greet>
          <font size="+2">Hello Joe!</font>
          </#macro>
          
          作為用戶定義指令使用宏變量時(shí),使用@替代FTL標(biāo)記中的#
          <@greet></@greet>
          
          如果沒(méi)有體內(nèi)容,也可以使用:
          <@greet/>
          
          • 參數(shù)

          在macro指令中可以在宏變量之后定義參數(shù),如:

          <#macro greet person>
          <font size="+2">Hello ${person}!</font>
          </#macro>
          
          可以這樣使用這個(gè)宏變量:
          <@greet person="Fred"/> and <@greet person="Batman"/>
          
          輸出結(jié)果是:
            <font size="+2">Hello Fred!</font>
          and   <font size="+2">Hello Batman!</font>
          

          宏的參數(shù)是FTL表達(dá)式,所以下面的代碼具有不同的意思:

          <@greet person=Fred/>
          
          這意味著將Fred變量的值傳給person參數(shù),該值不僅是字符串,還可以是其它類型,甚至是復(fù)雜的表達(dá)式

          可以有多參數(shù),下面是一個(gè)例子:

          <#macro greet person color>
          <font size="+2" color="${color}">Hello ${person}!</font>
          </#macro>
          
          可以這樣使用該宏變量:
          <@greet person="Fred" color="black"/>
          
          其中參數(shù)的次序是無(wú)關(guān)的,因此下面是等價(jià)的:
          <@greet color="black" person="Fred"/>
          
          只能使用在macro指令中定義的參數(shù),并且對(duì)所有參數(shù)賦值,所以下面的代碼是錯(cuò)誤的:
          <@greet person="Fred" color="black" background="green"/>
          <@greet person="Fred"/>
          
          可以在定義參數(shù)時(shí)指定缺省值,如:
          <#macro greet person color="black">
          <font size="+2" color="${color}">Hello ${person}!</font>
          </#macro>
          
          這樣<@greet person="Fred"/>就正確了

          宏的參數(shù)是局部變量,只能在宏定義中有效

          • 嵌套內(nèi)容

          用戶定義指令可以有嵌套內(nèi)容,使用<#nested>指令執(zhí)行指令開(kāi)始和結(jié)束標(biāo)記之間的模板片斷

          例子:

          <#macro border>
          <table border=4 cellspacing=0 cellpadding=4><tr><td>
          <#nested>
          </tr></td></table>
          </#macro>
          
          這樣使用該宏變量:
          <@border>The bordered text</@border>
          
          輸出結(jié)果:
            <table border=4 cellspacing=0 cellpadding=4><tr><td>
          The bordered text
          </tr></td></table>
          

          <#nested>指令可以被多次調(diào)用,例如:

          <#macro do_thrice>
          <#nested>
          <#nested>
          <#nested>
          </#macro>
          <@do_thrice>
          Anything.
          </@do_thrice>
          
          輸出結(jié)果:
            Anything.
          Anything.
          Anything.
          
          嵌套內(nèi)容可以是有效的FTL,下面是一個(gè)有些復(fù)雜的例子: <@border> <ul> <@do_thrice> <li><@greet person="Joe"/> </@do_thrice> </ul> </@border> }}} 輸出結(jié)果:
            <table border=4 cellspacing=0 cellpadding=4><tr><td>
          <ul>
          <li><font size="+2">Hello Joe!</font>
          <li><font size="+2">Hello Joe!</font>
          <li><font size="+2">Hello Joe!</font>
          </ul>
          </tr></td></table>
          
          宏定義中的局部變量對(duì)嵌套內(nèi)容是不可見(jiàn)的,例如:
          <#macro repeat count>
          <#local y = "test">
          <#list 1..count as x>
          ${y} ${count}/${x}: <#nested>
          </#list>
          </#macro>
          <@repeat count=3>${y?default("?")} ${x?default("?")} ${count?default("?")}</@repeat>
          
          輸出結(jié)果:
              test 3/1: ? ? ?
          test 3/2: ? ? ?
          test 3/3: ? ? ?
          
          • 在宏定義中使用循環(huán)變量

          用戶定義指令可以有循環(huán)變量,通常用于重復(fù)嵌套內(nèi)容,基本用法是:作為nested指令的參數(shù)傳遞循環(huán)變量的實(shí)際值,而在調(diào)用用戶定義指令時(shí),在<@…>開(kāi)始標(biāo)記的參數(shù)后面指定循環(huán)變量的名字

          例子:

          <#macro repeat count>
          <#list 1..count as x>
          <#nested x, x/2, x==count>
          </#list>
          </#macro>
          <@repeat count=4 ; c, halfc, last>
          ${c}. ${halfc}<#if last> Last!</#if>
          </@repeat>
          
          輸出結(jié)果:
            1. 0.5
          2. 1
          3. 1.5
          4. 2 Last!
          

          指定的循環(huán)變量的數(shù)目和用戶定義指令開(kāi)始標(biāo)記指定的不同不會(huì)有問(wèn)題

          調(diào)用時(shí)少指定循環(huán)變量,則多指定的值不可見(jiàn)

          調(diào)用時(shí)多指定循環(huán)變量,多余的循環(huán)變量不會(huì)被創(chuàng)建

          (2)在模板中定義變量

          在模板中定義的變量有三種類型:

          • plain變量:可以在模板的任何地方訪問(wèn),包括使用include指令插入的模板,使用assign指令創(chuàng)建和替換
          • 局部變量:在宏定義體中有效,使用local指令創(chuàng)建和替換
          • 循環(huán)變量:只能存在于指令的嵌套內(nèi)容,由指令(如list)自動(dòng)創(chuàng)建

          宏的參數(shù)是局部變量,而不是循環(huán)變量;局部變量隱藏(而不是覆蓋)同名的plain變量;循環(huán)變量隱藏同名的局部變量和plain變量,下面是一個(gè)例子:

          <#assign x = "plain">
          1. ${x}  <#-- we see the plain var. here -->
          <@test/>
          6. ${x}  <#-- the value of plain var. was not changed -->
          <#list ["loop"] as x>
          7. ${x}  <#-- now the loop var. hides the plain var. -->
          <#assign x = "plain2"> <#-- replace the plain var, hiding does not mater here -->
          8. ${x}  <#-- it still hides the plain var. -->
          </#list>
          9. ${x}  <#-- the new value of plain var. -->
          <#macro test>
          2. ${x}  <#-- we still see the plain var. here -->
          <#local x = "local">
          3. ${x}  <#-- now the local var. hides it -->
          <#list ["loop"] as x>
          4. ${x}  <#-- now the loop var. hides the local var. -->
          </#list>
          5. ${x}  <#-- now we see the local var. again -->
          </#macro>
          
          輸出結(jié)果:
          1. plain
          2. plain
          3. local
          4. loop
          5. local
          6. plain
          7. loop
          8. loop
          9. plain2
          

          內(nèi)部循環(huán)變量隱藏同名的外部循環(huán)變量,如:

          <#list ["loop 1"] as x>
          ${x}
          <#list ["loop 2"] as x>
          ${x}
          <#list ["loop 3"] as x>
          ${x}
          </#list>
          ${x}
          </#list>
          ${x}
          </#list>
          
          輸出結(jié)果:
            loop 1
          loop 2
          loop 3
          loop 2
          loop 1
          
          模板中的變量會(huì)隱藏(而不是覆蓋)數(shù)據(jù)模型中同名變量,如果需要訪問(wèn)數(shù)據(jù)模型中的同名變量,使用特殊變量global,下面的例子假設(shè)數(shù)據(jù)模型中的user的值是Big Joe:
          <#assign user = "Joe Hider">
          ${user}          <#-- prints: Joe Hider -->
          ${.globals.user} <#-- prints: Big Joe -->
          

          (3)名字空間

          通常情況,只使用一個(gè)名字空間,稱為主名字空間

          為了創(chuàng)建可重用的宏、變換器或其它變量的集合(通常稱庫(kù)),必須使用多名字空間,其目的是防止同名沖突

          • 創(chuàng)建庫(kù)

          下面是一個(gè)創(chuàng)建庫(kù)的例子(假設(shè)保存在lib/my_test.ftl中):

          <#macro copyright date>
          <p>Copyright (C) ${date} Julia Smith. All rights reserved.
          <br>Email: ${mail}</p>
          </#macro>
          <#assign mail = "jsmith@acme.com">
          
          使用import指令導(dǎo)入庫(kù)到模板中,F(xiàn)reemarker會(huì)為導(dǎo)入的庫(kù)創(chuàng)建新的名字空間,并可以通過(guò)import指令中指定的散列變量訪問(wèn)庫(kù)中的變量:
          <#import "/lib/my_test.ftl" as my>
          <#assign mail="fred@acme.com">
          <@my.copyright date="1999-2002"/>
          ${my.mail}
          ${mail}
          
          輸出結(jié)果:
            <p>Copyright (C) 1999-2002 Julia Smith. All rights reserved.
          <br>Email: jsmith@acme.com</p>
          jsmith@acme.com
          fred@acme.com
          
          可以看到例子中使用的兩個(gè)同名變量并沒(méi)有沖突,因?yàn)樗鼈兾挥诓煌拿挚臻g

          可以使用assign指令在導(dǎo)入的名字空間中創(chuàng)建或替代變量,下面是一個(gè)例子:

          <#import "/lib/my_test.ftl" as my>
          ${my.mail}
          <#assign mail="jsmith@other.com" in my>
          ${my.mail}
          
          輸出結(jié)果:
          jsmith@acme.com
          jsmith@other.com
          
          數(shù)據(jù)模型中的變量任何地方都可見(jiàn),也包括不同的名字空間,下面是修改的庫(kù):
          <#macro copyright date>
          <p>Copyright (C) ${date} ${user}. All rights reserved.</p>
          </#macro>
          <#assign mail = "${user}@acme.com">
          
          假設(shè)數(shù)據(jù)模型中的user變量的值是Fred,則下面的代碼:
          <#import "/lib/my_test.ftl" as my>
          <@my.copyright date="1999-2002"/>
          ${my.mail}
          
          輸出結(jié)果:
            <p>Copyright (C) 1999-2002 Fred. All rights reserved.</p>
          Fred@acme.com
          
          posted @ 2008-08-12 14:14 飛飛 閱讀(245) | 評(píng)論 (0)編輯 收藏

          <a href="javascript:void(window.open('1.htm','_blank','toolbar=no,scrollbar=no,top=50,left=50,width=100,height=100'));" >Open 1.htm</a>

          <a href="javascript: var win=window.open
          ('1.htm','_blank','toolbar=no,scrollbar=no,top=50,left=50,width=100,height=100')" >Open
          1.htm</a>
          最好。
          <a href="#" onclick="window.open('1.htm','_blank','toolbar=no,scrollbar=no,top=50,left=50,width=100,height=100')" >Open 1.htm</a>
          點(diǎn)擊后,原窗口的聯(lián)接地址會(huì)發(fā)生變化,加上了#,感覺(jué)不太好:)雖然也能實(shí)現(xiàn)功能
          posted @ 2008-08-11 18:44 飛飛 閱讀(986) | 評(píng)論 (2)編輯 收藏

          視圖解析器的一些屬性

          <bean id="viewResolver"

                class="org.springframework.web.servlet.view.InternalResourceViewResolver">

              <property name="exposeSpringMacroHelpers" value="true"/>

              <property name="requestContextAttribute" value="rc"/>

              <property name="viewClass" value="org.springframework.web.servlet.view.JstlView"/>

              <property name="prefix" value="/"/>

              <property name="suffix" value=".jsp"/>

          </bean>

          在視圖解析器的定義中,“exposeSpringMacroHelpers”設(shè)置是否通過(guò)Spring的宏庫(kù)暴露一個(gè)RequestContext(名為springBindRequestContext)供外部使用,默認(rèn)值為false。它暴露了處理表單和驗(yàn)證錯(cuò)誤信息的宏操作;

          requestContextAttribute”把SpringRequestContext對(duì)象暴露為變量rc。利用${rc.contextPath}來(lái)獲取應(yīng)用程序的contextPath(也就是/MyUsers);利用${rc.getMessage("user.name")}讀取/WEB-INF/classes/messages.properties本地化信息。此對(duì)象對(duì)于那些不訪問(wèn)serlvet請(qǐng)求的View技術(shù)(也就是VelocityFreeMarker模板)來(lái)說(shuō)是必不可少的。

          還有一些屬性:

          exposeRequestAttributes:默認(rèn)值false,設(shè)置是否所有的request屬性在與模板進(jìn)行合并之前添加到model中。(可以理解為request范圍內(nèi)包含的所有對(duì)象,而不是一個(gè)真正的Request對(duì)象。)

          exposeSessionAttributes:默認(rèn)值false,設(shè)置是否所有的session屬性在與模板進(jìn)行合并之前添加到model中。(理解同上)

          posted @ 2008-08-11 17:20 飛飛 閱讀(488) | 評(píng)論 (0)編輯 收藏

          Step 1:配置web.xml
          <?xml version="1.0" encoding="UTF-8"?>
          <web-app version="2.4" xmlns="http://java.sun.com/xml/ns/j2ee"
              xmlns:xsi
          ="http://www.w3.org/2001/XMLSchema-instance"
              xsi:schemaLocation
          ="http://java.sun.com/xml/ns/j2ee 
              http://java.sun.com/xml/ns/j2ee/web-app_2_4.xsd"
          >


              
          <display-name>springapp</display-name>
                  
              
          <servlet>
                  
          <servlet-name>springMVC</servlet-name>
                  
          <servlet-class>
                      org.springframework.web.servlet.DispatcherServlet
                  
          </servlet-class>
                  
          <load-on-startup>1</load-on-startup>
              
          </servlet>

              
          <servlet-mapping>
                  
          <servlet-name>springMVC</servlet-name>
                  
          <url-pattern>/page/*</url-pattern>
              
          </servlet-mapping>

          </web-app>
          servlet-mapping定義所有以/page/開(kāi)頭的url請(qǐng)求都會(huì)被spring 的DispatcherServlet處理轉(zhuǎn)發(fā)。默認(rèn)情況下DispatcherServlet會(huì)讀取<servlet-name>-servlet.xml文件的配置信息初始化,該文件中urlMapping的定義決定當(dāng)前請(qǐng)求轉(zhuǎn)發(fā)給哪個(gè)controller來(lái)處理。

          Step2:
          定義/WEB-INF/springMVC-servlet.xml
           
          <?xml version="1.0" encoding="UTF-8"?>
          <!DOCTYPE beans PUBLIC "-//SPRING//DTD BEAN//EN" "http://www.springframework.org/dtd/spring-beans.dtd">

          <beans>
              
          <!-- 方法名解析器 -->
              
          <bean id="InternalPathMethodNameResolver"
                  class
          ="org.springframework.web.servlet.mvc.multiaction.InternalPathMethodNameResolver" />
                  
              
          <!-- 視圖解析器 -->
              
          <bean id="viewResolver"
                  class
          ="org.springframework.web.servlet.view.InternalResourceViewResolver">
                  
          <property name="viewClass">
                      
          <value>org.springframework.web.servlet.view.JstlView</value>
                  
          </property>
              
          </bean>
              
              
          <bean id="controller" class="com.controller.IndexController">
                  
          <property name="methodNameResolver">
                      
          <ref bean="InternalPathMethodNameResolver" />
                  
          </property>
              
          </bean>

              
          <bean id="urlMapping"
                  class
          ="org.springframework.web.servlet.handler.SimpleUrlHandlerMapping">
                  
          <property name="mappings">
                      
          <props>
                          
          <prop key="/controller/*">controller</prop>
                      
          </props>
                  
          </property>
              
          </bean>
          </beans>
          urlMapping定義/controller/開(kāi)頭的url請(qǐng)求由名字為controller的控制器來(lái)處理,因?yàn)槭嵌鄤?dòng)作處理器,所以要定義MethodNameResolver來(lái)告訴springMVC應(yīng)該調(diào)用controller的哪個(gè)方法,這里用的是InternalPathMethodNameResolver,該方法名解釋器會(huì)把整個(gè)URL中最后一個(gè)"/"和最后一個(gè)"."之間的部分作為要調(diào)用的方法名

          Step3:定義controller類并繼承MultiActionController 
          package com.controller;

          import
           java.io.IOException;
          import
           java.util.HashMap;
          import
           java.util.Map;

          import
           javax.servlet.ServletException;
          import
           javax.servlet.http.HttpServletRequest;
          import
           javax.servlet.http.HttpServletResponse;

          import
           org.springframework.web.servlet.ModelAndView;
          import
           org.springframework.web.servlet.mvc.multiaction.MultiActionController;

          public class IndexController extends MultiActionController 
          {
              
              
          public
           ModelAndView method1(HttpServletRequest request,
                      HttpServletResponse respnose) 
          throws ServletException, IOException 
          {
                  Map model 
          = new
           HashMap();
                  model.put(
          "message""你調(diào)用的是方法1"
          );
                  
          return new ModelAndView("/index.jsp""model"
          , model);
              }

              
              
          public ModelAndView method2(HttpServletRequest request,
                      HttpServletResponse respnose) 
          throws ServletException, IOException 
          {
                  Map model 
          = new
           HashMap();
                  model.put(
          "message""你調(diào)用的是方法2"
          );
                  
          return new ModelAndView("/index.jsp""model"
          , model);
              }

          }


          通過(guò)配置文件,訪問(wèn)上面這個(gè)controller中某個(gè)方法的url即為:localhost:8080/page/controller/方法名


          Step4:/index.jsp
          <%@ page language="java" pageEncoding="UTF-8"%>
          <%@ taglib prefix="c" uri="http://java.sun.com/jstl/core_rt" %>
          <%@ taglib prefix="fmt" uri="http://java.sun.com/jstl/fmt"%> 


          <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">

          <html>
          <head></head>  
          <body>

              
          <c:out value="${model.message}"/>
          </body>
          </html>
          因?yàn)?font color="#0000ff">InternalPathMethodNameResolver方法名解釋器會(huì)把整個(gè)URL中最后一個(gè)"/"和最后一個(gè)"."之間的部分作為要調(diào)用的方法名,所以你可以在這個(gè)URL后面加任意文件格式的后綴,比如:
          localhost:8080/page/controller/method1.jsp

          localhost:8080/page/controller/method2.html
          很爽吧,和真實(shí)的URL地址一樣。


          另:開(kāi)發(fā)環(huán)境:MyEclipse5.0M2+tomcat5.5
            需要用到spring.jar和jstl.jar兩個(gè)包。
          posted @ 2008-08-11 16:02 飛飛 閱讀(218) | 評(píng)論 (0)編輯 收藏

          servlet 2.5的寫(xiě)法
              <web-app xmlns="http://java.sun.com/xml/ns/j2ee"
          xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
          xsi:schemaLocation="http://java.sun.com/xml/ns/j2ee
          http://java.sun.com/xml/ns/j2ee/web-app_2_5.xsd"
          version="2.5">

          別以為看到這里就結(jié)束了,很可惜地告訴你,這段代碼是錯(cuò)誤的。不信你嘗試打開(kāi)一下這個(gè)鏈接http://java.sun.com/xml/ns/j2ee/web-app_2_5.xsd,你會(huì)發(fā)現(xiàn)是no page found。

          那為什么tomcat6的范例程序能夠工作呢,那是因?yàn)樵趖omcat6的lib里面,已經(jīng)存在這個(gè)文件,所以也不需要從網(wǎng)絡(luò)上面抓取。其實(shí)你按照這個(gè)web.xml寫(xiě)了servlet 2.5的程序,在tomcat6里面也是可以運(yùn)行的。

          可是當(dāng)我使用eclipse+xmlbuddy的時(shí)候,問(wèn)題就出來(lái)了,因?yàn)閣eb-app_2_5.xsd一直不能下載,xmlbuddy一直報(bào)錯(cuò),并且沒(méi)有語(yǔ)法提示功能。通過(guò)搜索,我發(fā)現(xiàn)了web-app_2_5.xsd的真實(shí)地址其實(shí)是http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd,而它的namespace是http://java.sun.com/xml/ns/javaee,于是代碼應(yīng)該改成:

              <web-app xmlns="http://java.sun.com/xml/ns/javaee"
          xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
          xsi:schemaLocation="http://java.sun.com/xml/ns/javaee
          http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd"
          version="2.5">

          留意一下不同的部分,其實(shí)是因?yàn)閟un把j2ee改名為javaee。

          ps,另外附上servlet 2.4的寫(xiě)法

              <web-app xmlns="http://java.sun.com/xml/ns/j2ee"
          xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
          xsi:schemaLocation="http://java.sun.com/xml/ns/j2ee
          http://java.sun.com/xml/ns/j2ee/web-app_2_4.xsd"
          version="2.4">
          posted @ 2008-08-11 10:13 飛飛 閱讀(541) | 評(píng)論 (0)編輯 收藏

          1. 實(shí)體(表)的命名
            1) 表以名詞或名詞短語(yǔ)命名,確定表名是采用復(fù)數(shù)還是單數(shù)形式,此外給表的別名定義簡(jiǎn)單規(guī)則(比方說(shuō),如果表名是一個(gè)單詞,別名就取單詞的前4 個(gè)字母;如果表名是兩個(gè)單詞,就各取兩個(gè)單詞的前兩個(gè)字母組成4 個(gè)字母長(zhǎng)的別名;如果表的名字由3 個(gè)單詞組成,從頭兩個(gè)單詞中各取一個(gè)然后從最后一個(gè)單詞中再取出兩個(gè)字母,結(jié)果還是組成4 字母長(zhǎng)的別名,其余依次類推)
            對(duì)工作用表來(lái)說(shuō),表名可以加上前綴WORK_ 后面附上采用該表的應(yīng)用程序的名字。在命名過(guò)程當(dāng)中,根據(jù)語(yǔ)義拼湊縮寫(xiě)即可。注意,由于ORCLE會(huì)將字段名稱統(tǒng)一成大寫(xiě)或者小寫(xiě)中的一種,所以要求加上下劃線。
            舉例:
            定義的縮寫(xiě) Sales: Sal 銷售;
            Order: Ord 訂單;
            Detail: Dtl 明細(xì);
            則銷售訂單明細(xì)表命名為:Sal_Ord_Dtl;
            2) 如果表或者是字段的名稱僅有一個(gè)單詞,那么建議不使用縮寫(xiě),而是用完整的單詞。
            舉例:
            定義的縮寫(xiě) Material Ma 物品;
            物品表名為:Material, 而不是 Ma.
            但是字段物品編碼則是:Ma_ID;而不是Material_ID
            3) 所有的存儲(chǔ)值列表的表前面加上前綴Z
            目的是將這些值列表類排序在數(shù)據(jù)庫(kù)最后。
            4) 所有的冗余類的命名(主要是累計(jì)表)前面加上前綴X
            冗余類是為了提高數(shù)據(jù)庫(kù)效率,非規(guī)范化數(shù)據(jù)庫(kù)的時(shí)候加入的字段或者表
            5) 關(guān)聯(lián)類通過(guò)用下劃線連接兩個(gè)基本類之后,再加前綴R的方式命名,后面按照字母順序羅列兩個(gè)表名或者表名的縮寫(xiě)。
            關(guān)聯(lián)表用于保存多對(duì)多關(guān)系。
            如果被關(guān)聯(lián)的表名大于10個(gè)字母,必須將原來(lái)的表名的進(jìn)行縮寫(xiě)。如果沒(méi)有其他原因,建議都使用縮寫(xiě)。
            舉例:表Object與自身存在多對(duì)多的關(guān)系,則保存多對(duì)多關(guān)系的表命名為:R_Object;
            表 Depart和Employee;存在多對(duì)多的關(guān)系;則關(guān)聯(lián)表命名為R_Dept_Emp
            2. 屬性(列)的命名
            1) 采用有意義的列名,表內(nèi)的列要針對(duì)鍵采用一整套設(shè)計(jì)規(guī)則。每一個(gè)表都將有一個(gè)自動(dòng)ID作為主健,邏輯上的主健作為第一組候選主健來(lái)定義,如果是數(shù)據(jù)庫(kù)自動(dòng)生成的編碼,統(tǒng)一命名為:ID;如果是自定義的邏輯上的編碼則用縮寫(xiě)加“ID”的方法命名。如果鍵是數(shù)字類型,你可以用_NO 作為后綴;如果是字符類型則可以采用_CODE 后綴。對(duì)列名應(yīng)該采用標(biāo)準(zhǔn)的前綴和后綴。
            舉例:銷售訂單的編號(hào)字段命名:Sal_Ord_ID;如果還存在一個(gè)數(shù)據(jù)庫(kù)生成的自動(dòng)編號(hào),則命名為:ID。
            2) 所有的屬性加上有關(guān)類型的后綴,注意,如果還需要其它的后綴,都放在類型后綴之前。
            注: 數(shù)據(jù)類型是文本的字段,類型后綴TX可以不寫(xiě)。有些類型比較明顯的字段,可以不寫(xiě)類型后綴。
            3) 采用前綴命名
            給每個(gè)表的列名都采用統(tǒng)一的前綴,那么在編寫(xiě)SQL表達(dá)式的時(shí)候會(huì)得到大大的簡(jiǎn)化。這樣做也確實(shí)有缺點(diǎn),比如破壞了自動(dòng)表連接工具的作用,后者把公共列名同某些數(shù)據(jù)庫(kù)聯(lián)系起來(lái)。
            3. 視圖的命名
            1) 視圖以V作為前綴,其他命名規(guī)則和表的命名類似;
            2) 命名應(yīng)盡量體現(xiàn)各視圖的功能
            4. 觸發(fā)器的命名
            觸發(fā)器以TR作為前綴,觸發(fā)器名為相應(yīng)的表名加上后綴,Insert觸發(fā)器加"_I",Delete觸發(fā)器加"_D",Update觸發(fā)器加"_U",如:

            TR_Customer_I,TR_Customer_D,TR_Customer_U。
            5. 存儲(chǔ)過(guò)程名
            存儲(chǔ)過(guò)程應(yīng)以"UP_"開(kāi)頭,和系統(tǒng)的存儲(chǔ)過(guò)程區(qū)分,后續(xù)部分主要以動(dòng)賓形式構(gòu)成,并用下劃線分割各個(gè)組成部分。如增加代理商的帳戶的存儲(chǔ)過(guò)程為"UP_Ins_Agent_Account"。
            6. 變量名
            變量名采用小寫(xiě),若屬于詞組形式,用下劃線分隔每個(gè)單詞,如@my_err_no。
            7. 命名中其他注意事項(xiàng)
            1)  以上命名都不得超過(guò)30個(gè)字符的系統(tǒng)限制。變量名的長(zhǎng)度限制為29(不包括標(biāo)識(shí)字符@)。
            2)  數(shù)據(jù)對(duì)象、變量的命名都采用英文字符,禁止使用中文命名。絕對(duì)不要在對(duì)象名的字符之間留空格。
            3) 小心保留詞,要保證你的字段名沒(méi)有和保留詞、數(shù)據(jù)庫(kù)系統(tǒng)或者常用訪問(wèn)方法沖突
            5) 保持字段名和類型的一致性,在命名字段并為其指定數(shù)據(jù)類型的時(shí)候一定要保證一致性。假如數(shù)據(jù)類型在一個(gè)表里是整數(shù),那在另一個(gè)表里可就別變成字符型了。

          posted @ 2008-08-08 10:00 飛飛 閱讀(458) | 評(píng)論 (0)編輯 收藏

          如果底層數(shù)據(jù)庫(kù)(如Oracle)支持存儲(chǔ)過(guò)程,也可以通過(guò)存儲(chǔ)過(guò)程來(lái)執(zhí)行批量更新。存儲(chǔ)過(guò)程直接在數(shù)據(jù)庫(kù)中運(yùn)行,速度更加快。在Oracle數(shù)據(jù)庫(kù)中可以定義一個(gè)名為batchUpdateStudent()的存儲(chǔ)過(guò)程,代碼如下:

          create or replace procedure batchUpdateStudent(p_age in number) as
          begin
          update STUDENT set AGE=AGE+1 where AGE>p_age;
          end;

          以上存儲(chǔ)過(guò)程有一個(gè)參數(shù)p_age,代表學(xué)生的年齡,應(yīng)用程序可按照以下方式調(diào)用存儲(chǔ)過(guò)程:

          tx = session.beginTransaction();
          Connection con=session.connection();

          String procedure = "{call batchUpdateStudent(?) }";
          CallableStatement cstmt = con.prepareCall(procedure);
          cstmt.setInt(1,0); //把年齡參數(shù)設(shè)為0
          cstmt.executeUpdate();
          tx.commit();

          在以上代碼中,用的是Hibernate的 Transaction接口來(lái)聲明事務(wù),而不是采用JDBC API來(lái)聲明事務(wù)。

          posted @ 2008-08-08 09:53 飛飛 閱讀(350) | 評(píng)論 (0)編輯 收藏

          BUG1
          2008-08-07 11:25:01,015 DEBUG (FacesSetupInterceptor.java:136) - Unable to initialize faces
           java.lang.IllegalStateException: Application was not properly initialized at startup, could not find Factory: javax.faces.context.FacesContextFactory
           at javax.faces.FactoryFinder.getFactory(FactoryFinder.java:256)
           at org.apache.struts2.jsf.FacesSetupInterceptor.init(FacesSetupInterceptor.java:133)
           at com.opensymphony.xwork2.ObjectFactory.buildInterceptor(ObjectFactory.java:186)
           at com.opensymphony.xwork2.config.providers.InterceptorBuilder.constructInterceptorReference(InterceptorBuilder.java:57)
           at com.opensymphony.xwork2.config.providers.XmlConfigurationProvider.lookupInterceptorReference(XmlConfigurationProvider.java:905)
           at com.opensymphony.xwork2.config.providers.XmlConfigurationProvider.loadInterceptorStack(XmlConfigurationProvider.java:743)
           at com.opensymphony.xwork2.config.providers.XmlConfigurationProvider.loadInterceptorStacks(XmlConfigurationProvider.java:756)
           at com.opensymphony.xwork2.config.providers.XmlConfigurationProvider.loadInterceptors(XmlConfigurationProvider.java:777)
           at com.opensymphony.xwork2.config.providers.XmlConfigurationProvider.addPackage(XmlConfigurationProvider.java:410)
           at com.opensymphony.xwork2.config.providers.XmlConfigurationProvider.loadPackages(XmlConfigurationProvider.java:239)
           at org.apache.struts2.config.StrutsXmlConfigurationProvider.loadPackages(StrutsXmlConfigurationProvider.java:111)
           at com.opensymphony.xwork2.config.impl.DefaultConfiguration.reload(DefaultConfiguration.java:152)
           at com.opensymphony.xwork2.config.ConfigurationManager.getConfiguration(ConfigurationManager.java:52)
           at org.apache.struts2.dispatcher.Dispatcher.init_PreloadConfiguration(Dispatcher.java:395)
           at org.apache.struts2.dispatcher.Dispatcher.init(Dispatcher.java:452)
           at org.apache.struts2.dispatcher.FilterDispatcher.init(FilterDispatcher.java:201)
           at org.apache.catalina.core.ApplicationFilterConfig.getFilter(ApplicationFilterConfig.java:275)
           at org.apache.catalina.core.ApplicationFilterConfig.setFilterDef(ApplicationFilterConfig.java:397)
           at org.apache.catalina.core.ApplicationFilterConfig.<init>(ApplicationFilterConfig.java:108)
           at org.apache.catalina.core.StandardContext.filterStart(StandardContext.java:3693)
           at org.apache.catalina.core.StandardContext.start(StandardContext.java:4340)
           at org.apache.catalina.core.ContainerBase.addChildInternal(ContainerBase.java:791)
           at org.apache.catalina.core.ContainerBase.addChild(ContainerBase.java:771)
           at org.apache.catalina.core.StandardHost.addChild(StandardHost.java:525)
           at org.apache.catalina.startup.HostConfig.deployDirectory(HostConfig.java:920)
           at org.apache.catalina.startup.HostConfig.deployDirectories(HostConfig.java:883)
           at org.apache.catalina.startup.HostConfig.deployApps(HostConfig.java:492)
           at org.apache.catalina.startup.HostConfig.start(HostConfig.java:1138)
           at org.apache.catalina.startup.HostConfig.lifecycleEvent(HostConfig.java:311)
           at org.apache.catalina.util.LifecycleSupport.fireLifecycleEvent(LifecycleSupport.java:117)
           at org.apache.catalina.core.ContainerBase.start(ContainerBase.java:1053)
           at org.apache.catalina.core.StandardHost.start(StandardHost.java:719)
           at org.apache.catalina.core.ContainerBase.start(ContainerBase.java:1045)
           at org.apache.catalina.core.StandardEngine.start(StandardEngine.java:443)
           at org.apache.catalina.core.StandardService.start(StandardService.java:516)
           at org.apache.catalina.core.StandardServer.start(StandardServer.java:710)
           at org.apache.catalina.startup.Catalina.start(Catalina.java:566)
           at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
           at sun.reflect.NativeMethodAccessorImpl.invoke(Unknown Source)
           at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source)
           at java.lang.reflect.Method.invoke(Unknown Source)
           at org.apache.catalina.startup.Bootstrap.start(Bootstrap.java:288)
           at org.apache.catalina.startup.Bootstrap.main(Bootstrap.java:413)

          這個(gè)錯(cuò)誤是由配置文件引起。在session-factory段加入:
          <property name="current_session_context_class">thread</property>
          posted @ 2008-08-07 11:31 飛飛 閱讀(434) | 評(píng)論 (0)編輯 收藏

               摘要: 一. 簡(jiǎn)介 1. 簡(jiǎn)介 目前的版本是:4.0 正式版 發(fā)布于2008-05-30 2. 注意事項(xiàng) My97DatePicker目錄是一個(gè)整體,不可破壞里面的目錄結(jié)構(gòu),也不可對(duì)里面的文件改名,可以改目錄名 My97DatePicker.htm是必須文件,不可刪除 各目錄及文件的用途: WdatePicker.js 配置文件,在調(diào)用的地方僅需使用該文...  閱讀全文
          posted @ 2008-08-06 09:09 飛飛 閱讀(3016) | 評(píng)論 (0)編輯 收藏

          1、MyEclipse下建立新的Web Porject

          2、Copy Struts2的lib文件到工程的WEB-INF/lib下非*-plugin-2.0.6.jar的所有的包加上struts2-spring- plugin-2.0.6.jar,最小的包可以在struts-2.0.6\apps\struts2-blank-2.0.6\WEB-INF\ lib下找到,不過(guò)因?yàn)槭褂肧pring、Hiberate那點(diǎn)包是不夠用的

          3.1、工程名上右鍵->MyEclipse->Add Spring Capabilities點(diǎn)擊出現(xiàn)對(duì)話框

          3.2、由于我用的MyEclipse中Spring的插件是1.2的,所以沒(méi)使用MyEclipse下的包,不選擇MyEclipse Libraries

          3.3、選中Copy checked library contents to project folder (TLDs always copied)

          3.4、使用默認(rèn)的Library Folder:/WebRoot/WEB-INF/lib,Next

          3.5、Folder點(diǎn)周Brower選中項(xiàng)目的WebRoot/WEB-INF/

          3.6、點(diǎn)擊Finish

          4、配置MyEclipse數(shù)據(jù)庫(kù)設(shè)置

          4.1、菜單Windows->Preferences->MyEclipse->Database Explorer->Drivers

          4.2、點(diǎn)擊New設(shè)置數(shù)據(jù)庫(kù)連接,例:
          Driver template : Oracle (Thin driver)
          Driver name : Oracle (Thin driver)
          Connection URL : jdbc:oracle:thin:@<server>[:<1521>]:<database_name>
          Driver JARs: ojdbc14.jar
          Dirver classname : oracle.jdbc.driver.OracleDriver

          4.3、點(diǎn)擊OK、OK

          5、忘了Copy Spring 2的jar包到工程中了,不過(guò)沒(méi)關(guān)系,現(xiàn)在Copy也一樣,Copy spring-framework-2.0.3\dist\spring.jar 到/WebRoot/WEB-INF/lib下就可以了,如果想Copy專用的包可以Copy spring-framework-2.0.3\dist\modules下的

          5.1、菜單Windows->Open perspective->MyEclipse Database Explorer

          5.2、在DB Brower點(diǎn)右鍵->New

          5.3、配置例子如下:
          Profile name: test
          Driver: Oracle (Thin driver)
          URL: jdbc:oracle:thin:@127.0.0.1:1521:test
          User name: test
          Password: test
          選中Save password

          5.4、點(diǎn)擊Finish

          6.1、配置Hibernate

          6.2 工程名上右鍵->MyEclipse->Add Hiberate Capabilities點(diǎn)擊出現(xiàn)對(duì)話框

          6.3、選中Copy checked Library Jars to project forlder and add to build-path 點(diǎn)擊Next

          6.4、選中Spring configuration file (applicationContext.xml)點(diǎn)擊Next

          6.5、選中Existing Spring configuration file,MyEclipse會(huì)幫你自動(dòng)找到Spring Config文件的

          6.6、SessionFactory ID填寫(xiě)sessionFactory點(diǎn)擊Next

          6.7、Bean Id填寫(xiě)dataSource,選中DB Profile下剛才建好的test,點(diǎn)擊Next

          6.8、不選擇Create SessionFactory class?點(diǎn)擊Finish

          7、這時(shí)候會(huì)提示你某些類沒(méi)發(fā)現(xiàn),Copy commons-dbcp-1.2.1.jar到lib下就OK了


          8 配置struts.properties文件,指定spring作為struts的IoC容器
          struts.objectFactory = spring
          (1)默認(rèn)的autowiring模式是:by name
          即如果applicationContext.xml文件中的bean id與struts.xml文件中的action name相同,就
          (2)如果要改為其他模式:
          struts.objectFactory.spring.autoWire = name|type|auto|constructor

          例:

          struts.i18n.encoding=ISO-8859-1
          struts.locale=de_DE
          struts.objectFactory=spring
          ### Load custom default resource bundles
          struts.custom.i18n.resources=testmessages
          ### XSLT Cache
          struts.xslt.nocache = true


          9配置web.xml文件,啟動(dòng)Spring偵聽(tīng)器
          <listener>
          <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
          </listener>

          10 在WEB-INF目錄下的applicationContext.xml文件
          例:
          <?xml version="1.0" encoding="UTF-8"?>
          <!DOCTYPE beans PUBLIC "-//SPRING//DTD BEAN//EN" " <beans default-autowire="autodetect">
          <bean id="personManager" class="com.acme.PersonManager"/>
          </beans >

          11 設(shè)置由Spring來(lái)初始化action
          11.1  在Spring的applicationContext.xml文件中配置bean(即action類)
          11.2  將struts.xml中的action的class屬性,由class名改為Spring中定義的bean名
          例如:
          (1)applicationContext.xml中,定義bean id是bar
          <beans default-autowire="autodetect">
          <bean id="bar" class="com.my.BarClass" singleton="false"/>
          ...
          </beans>
          (2)struts.xml中,action的class="bar",而不是通常的類名
          <package name="secure" namespace="/secure" extends="default">
          <action name="bar" class="bar">
          <result>bar.ftl</result>
          </action>
          </package >

          啟動(dòng)運(yùn)行:
          報(bào)錯(cuò)
          log4j:WARN No appenders could be found for logger (org.springframework.core.CollectionFactory).
          log4j:WARN Please initialize the log4j system properly.
          2008-8-6 9:29:16 org.apache.catalina.core.ApplicationContext log
          信息: Initializing Spring root WebApplicationContext
          2008-8-6 9:29:18 org.apache.catalina.core.StandardContext listenerStart
          嚴(yán)重: Exception sending context initialized event to listener instance of class org.springframework.web.context.ContextLoaderListener
          org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'dataSource' defined in ServletContext resource [/WEB-INF/applicationContext.xml]: Instantiation of bean failed; nested exception is java.lang.NoClassDefFoundError: org/apache/commons/pool/impl/GenericObjectPool
           at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.instantiateBean(AbstractAutowireCapableBeanFactory.java:883)
           at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBeanInstance(AbstractAutowireCapableBeanFactory.java:839)
           at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:440)
           at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory$1.run(AbstractAutowireCapableBeanFactory.java:409)
           at java.security.AccessController.doPrivileged(Native Method)
           at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:380)
           at org.springframework.beans.factory.support.AbstractBeanFactory$1.getObject(AbstractBeanFactory.java:264)
           at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:221)
           at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:261)
           at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:185)
           at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:164)
           at org.springframework.beans.factory.support.DefaultListableBeanFactory.preInstantiateSingletons(DefaultListableBeanFactory.java:429)
           at org.springframework.context.support.AbstractApplicationContext.finishBeanFactoryInitialization(AbstractApplicationContext.java:729)
           at org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:381)
           at org.springframework.web.context.ContextLoader.createWebApplicationContext(ContextLoader.java:255)
           at org.springframework.web.context.ContextLoader.initWebApplicationContext(ContextLoader.java:199)
           at org.springframework.web.context.ContextLoaderListener.contextInitialized(ContextLoaderListener.java:45)
           at org.apache.catalina.core.StandardContext.listenerStart(StandardContext.java:3827)
           at org.apache.catalina.core.StandardContext.start(StandardContext.java:4334)
           at org.apache.catalina.core.ContainerBase.addChildInternal(ContainerBase.java:791)
           at org.apache.catalina.core.ContainerBase.addChild(ContainerBase.java:771)
           at org.apache.catalina.core.StandardHost.addChild(StandardHost.java:525)
           at org.apache.catalina.startup.HostConfig.deployDirectory(HostConfig.java:920)
           at org.apache.catalina.startup.HostConfig.deployDirectories(HostConfig.java:883)
           at org.apache.catalina.startup.HostConfig.deployApps(HostConfig.java:492)
           at org.apache.catalina.startup.HostConfig.start(HostConfig.java:1138)
           at org.apache.catalina.startup.HostConfig.lifecycleEvent(HostConfig.java:311)
           at org.apache.catalina.util.LifecycleSupport.fireLifecycleEvent(LifecycleSupport.java:117)
           at org.apache.catalina.core.ContainerBase.start(ContainerBase.java:1053)
           at org.apache.catalina.core.StandardHost.start(StandardHost.java:719)
           at org.apache.catalina.core.ContainerBase.start(ContainerBase.java:1045)
           at org.apache.catalina.core.StandardEngine.start(StandardEngine.java:443)
           at org.apache.catalina.core.StandardService.start(StandardService.java:516)
           at org.apache.catalina.core.StandardServer.start(StandardServer.java:710)
           at org.apache.catalina.startup.Catalina.start(Catalina.java:566)
           at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
           at sun.reflect.NativeMethodAccessorImpl.invoke(Unknown Source)
           at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source)
           at java.lang.reflect.Method.invoke(Unknown Source)
           at org.apache.catalina.startup.Bootstrap.start(Bootstrap.java:288)
           at org.apache.catalina.startup.Bootstrap.main(Bootstrap.java:413)
          Caused by: java.lang.NoClassDefFoundError: org/apache/commons/pool/impl/GenericObjectPool
           at java.lang.Class.getDeclaredConstructors0(Native Method)
           at java.lang.Class.privateGetDeclaredConstructors(Unknown Source)
           at java.lang.Class.getConstructor0(Unknown Source)
           at java.lang.Class.getDeclaredConstructor(Unknown Source)
           at org.springframework.beans.factory.support.SimpleInstantiationStrategy.instantiate(SimpleInstantiationStrategy.java:54)
           at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.instantiateBean(AbstractAutowireCapableBeanFactory.java:877)
           ... 40 more
          2008-8-6 9:29:18 org.apache.catalina.core.StandardContext start
          嚴(yán)重: Error listenerStart
          2008-8-6 9:29:18 org.apache.catalina.core.StandardContext start
          嚴(yán)重: Context [/ssh] startup failed due to previous errors

          原因:
          找不到 Caused by: java.lang.NoClassDefFoundError: org/apache/commons/pool/impl/GenericObjectPool
          就Apache所提供的基本對(duì)象池。

          解決:
          到這里
          http://commons.apache.org/downloads/download_pool.cgi下載包,然后,把里面的commons-pool-x.jar復(fù)制到項(xiàng)目的lib文件夾下

          錯(cuò)誤:
          log4j:WARN No appenders could be found for logger (org.springframework.core.CollectionFactory).
          log4j:WARN Please initialize the log4j system properly.

          解決:
          在WEB-INF/class 目錄下建立一個(gè)log4j.properties文件,內(nèi)容如下:
          log4j.rootLogger=DEBUG,stdout
          log4j.appender.stdout=org.apache.log4j.ConsoleAppender
          log4j.appender.stdout.layout=org.apache.log4j.PatternLayout
          log4j.appender.stdout.layout.ConversionPattern=%d %5p (%F:%L) - %m%n

          警告:

          信息: Starting Servlet Engine: Apache Tomcat/6.0.13
          log4j:WARN No appenders could be found for logger (org.apache.struts.util.PropertyMessageResources).
          log4j:WARN Please initialize the log4j system properly.
          2008-8-6 9:40:09 org.apache.catalina.core.ApplicationContext log
          信息: Initializing WebApplicationContext for Struts ActionServlet 'action', module ''
          2008-08-06 09:40:29,859 DEBUG (CollectionFactory.java:195) - Creating [java.util.concurrent.ConcurrentHashMap]
           2008-8-6 9:40:29 org.apache.catalina.core.ApplicationContext log
          信息: Initializing Spring root WebApplicationContext
          2008-08-06 09:40:29,906  INFO (ContextLoader.java:189) - Root WebApplicationContext: initialization started
           2008-08-06 09:40:30,203  INFO (AbstractApplicationContext.java:412) - Refreshing org.springframework.web.context.support.XmlWebApplicationContext@1df59bd: display name [Root WebApplicationContext]; startup date [Wed Aug 06 09:40:30 CST 2008]; root of context hierarchy
           2008-08-06 09:40:30,406 DEBUG (CollectionFactory.java:195) - Creating [java.util.concurrent.ConcurrentHashMap]


          index.jsp

          <%@ page language="java" pageEncoding="GBK"%>
          <%@ taglib prefix="s" uri="/struts-tags"%>
          <html>
           <head>
            <title>登錄</title>
            <style type="text/css">
          .label {
           font-style: italic;
          }

          .errorLabel {
           font-style: italic;
           color: red;
          }

          .errorMessage {
           font-weight: bold;
           color: red;
          }
          </style>
           </head>
           <s:head theme="ajax" />
           <body>
           <s:debug>
            <s:form action="First">
             <s:textfield name="username" label="用戶名" />
             <s:textfield name="password" label="密碼" />
             <s:submit value="登錄" />
             <s:a href="First.action">登錄</s:a>
            </s:form>
          </s:debug>
           </body>
          </html>



          BUG:
          2008-8-6 10:58:02 org.apache.catalina.core.StandardWrapperValve invoke
          嚴(yán)重: Servlet.service() for servlet jsp threw exception
          The Struts dispatcher cannot be found.  This is usually caused by using Struts tags without the associated filter. Struts tags are only usable when the request has passed through its servlet filter, which initializes the Struts dispatcher needed for this tag. - [unknown location]
           at org.apache.struts2.views.jsp.TagUtils.getStack(TagUtils.java:60)
           at org.apache.struts2.views.jsp.StrutsBodyTagSupport.getStack(StrutsBodyTagSupport.java:52)
           at org.apache.struts2.views.jsp.ComponentTagSupport.doStartTag(ComponentTagSupport.java:49)
           at org.apache.jsp.index_jsp._jspx_meth_s_005fhead_005f0(index_jsp.java:126)
           at org.apache.jsp.index_jsp._jspService(index_jsp.java:94)
           at org.apache.jasper.runtime.HttpJspBase.service(HttpJspBase.java:70)
           at javax.servlet.http.HttpServlet.service(HttpServlet.java:803)
           at org.apache.jasper.servlet.JspServletWrapper.service(JspServletWrapper.java:393)
           at org.apache.jasper.servlet.JspServlet.serviceJspFile(JspServlet.java:320)
           at org.apache.jasper.servlet.JspServlet.service(JspServlet.java:266)
           at javax.servlet.http.HttpServlet.service(HttpServlet.java:803)
           at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:290)
           at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:206)
           at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:230)
           at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:175)
           at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:128)
           at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:104)
           at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:109)
           at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:261)
           at org.apache.coyote.http11.Http11Processor.process(Http11Processor.java:844)
           at org.apache.coyote.http11.Http11Protocol$Http11ConnectionHandler.process(Http11Protocol.java:581)
           at org.apache.tomcat.util.net.JIoEndpoint$Worker.run(JIoEndpoint.java:447)
           at java.lang.Thread.run(Unknown Source)

          解決:web.xml添加
          <filter>
            <filter-name>struts2</filter-name>
            <filter-class>
             org.apache.struts2.dispatcher.FilterDispatcher
            </filter-class>
           </filter>
           <filter-mapping>
            <filter-name>struts2</filter-name>
            <url-pattern>/*</url-pattern>
           </filter-mapping>


          posted @ 2008-08-06 09:07 飛飛 閱讀(2009) | 評(píng)論 (0)編輯 收藏

          僅列出標(biāo)題
          共12頁(yè): 上一頁(yè) 1 2 3 4 5 6 7 8 9 下一頁(yè) Last 
          主站蜘蛛池模板: 洱源县| 名山县| 图木舒克市| 广丰县| 汉源县| 和平区| 峨眉山市| 巴林右旗| 涟源市| 通海县| 邛崃市| 盐边县| 梧州市| 仙居县| 宜春市| 大丰市| 堆龙德庆县| 卢龙县| 桃园市| 沙田区| 大关县| 鄢陵县| 汾西县| 乌兰县| 高邑县| 宁远县| 白沙| 崇阳县| 晋州市| 台安县| 上林县| 迁西县| 桐城市| 永仁县| 西乡县| 綦江县| 唐河县| 永川市| 景洪市| 横峰县| 吉林市|