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

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

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

    posts - 241,  comments - 116,  trackbacks - 0
    1. 前面講的自定義類型轉(zhuǎn)換器是基于 OGNL 的 DefaultTypeConverter 類并實(shí)現(xiàn) convertValue() 方法,兩個(gè)轉(zhuǎn)換方向的邏輯都寫在這一個(gè)方法中。而 Struts 2 為我們提供了一個(gè) DefaultTypeConverter 的抽象子類 StrutsTypeConverter 來(lái)繼承,并實(shí)現(xiàn)其中兩個(gè)抽象方法 convertFromString() 和 convertToString(),這要簡(jiǎn)單易懂。對(duì)比 Struts 1 的轉(zhuǎn)換器是要實(shí)現(xiàn) org.apache.commons.beanutils.Converter 接口,以及它的 convert() 方法的。

    2. 注意,上面的 convertFromString() 的第二個(gè)參數(shù)是一個(gè)字符串?dāng)?shù)組,所以可為請(qǐng)求的數(shù)組(如請(qǐng)求串為 ?u=1&u=2&u=3)定義轉(zhuǎn)換器,Action 中相應(yīng)的屬性就應(yīng)為數(shù)組或 List,這一方法的返回值也該為相應(yīng)的類型(數(shù)組或List,要通過(guò)第三個(gè)參數(shù) toClass 來(lái)判斷是返回?cái)?shù)組還是 List 了)。

    3. 字符串(如 "user,pass") 轉(zhuǎn)換成 Action 中的復(fù)合屬性(如 User user) 前面是自定了類型轉(zhuǎn)換器。除此之外,還可以 Struts 2 內(nèi)置的 OGNL 表達(dá)式,更簡(jiǎn)單的轉(zhuǎn)換,不用寫轉(zhuǎn)換器。例如,你的 Action 有屬性 User user,只要在 jsp 頁(yè)面的輸入框命名為 user.name  和 user.pass 即可:
            <input type="text" name="user.name"/> 或用標(biāo)簽:<s:textfield name="user.name" label="用戶名"/>
            <input type="text" name="user.pass"/>  或用標(biāo)簽:<s:textfield name="user.pass" label="密 碼"/>
        提交后,Struts 2 即會(huì)幫你構(gòu)造 User 對(duì)象(user = new User()),并賦上屬性值(user.setName(),user.setPass()),最后 user 對(duì)象賦給 Action (xxxAction.setUser(user))。所以要明白有三個(gè)必備的東西:
            1) User 要用一個(gè)默認(rèn)構(gòu)造方法 2) User 要有對(duì)應(yīng) name 和 pass 的設(shè)置方法 setName() 和 setPass() 3) Action 要有 user 屬性的設(shè)置方法 setUser(),getUser() 也是要的,至于功用后面能看到。
    其實(shí)在 Struts 1 中也有這種用法,不過(guò)那是在 BeanUtils 中實(shí)現(xiàn)的。

    4. 如果 Action 中的屬性是 Map<String, User> users; 那么與此對(duì)應(yīng)的表單寫法就是:(用標(biāo)簽來(lái)寫)
            <s:textfield name="users['one'].name" label="第一個(gè)用戶名"/>
            <s:textfield name="users['one'].name" label="第一個(gè)密碼"/>
            <s:textfield name="users['two'].name" label="第二個(gè)用戶名"/>
            <s:textfield name="users['two'].name" label="第二個(gè)密碼"/>
        應(yīng)該不難想像,這個(gè)表單提交后,users  中存儲(chǔ)的是什么吧!
        如果是對(duì)于 Action 中的  List 屬性,List<User> users; 那么與此對(duì)應(yīng)的表單寫法就是:
            <s:textfield name="users[0].name" label="第一個(gè)用戶名"/>
            <s:textfield name="users[0].name" label="第一個(gè)密碼"/>
            <s:textfield name="users[1].name" label="第二個(gè)用戶名"/>
            <s:textfield name="users[1].name" label="第二個(gè)密碼"/>

    5. 歸納前面3、4、5 幾點(diǎn),Struts2 的 Action 在設(shè)置每一個(gè)屬性時(shí)都會(huì) get 一下相應(yīng)的元素 getUser() 或 getUsers()。
        對(duì)于 3,在設(shè)置 user.name 和 user.pass 之前都會(huì) getUser() 來(lái)獲取 user 屬性,如果 user 為 null 就構(gòu)造 User 對(duì)象,然后設(shè)置相應(yīng)的值。假如聲明的時(shí)候就已構(gòu)造好 User 對(duì)象,如有其他屬性如 age=18,并不會(huì)被覆蓋。 
       對(duì)于 4 和 5,也是在設(shè)置每一個(gè)屬性前都會(huì)調(diào)用 getUsers() 判斷聲明的 Map 或 List 是否為 null,是則構(gòu)造對(duì)應(yīng)的 HashMap 或  ArrayList() 對(duì)象;接著根據(jù) Key 或下標(biāo)去獲取相應(yīng)位置的元素,如果不存在或?yàn)?null 則構(gòu)造之,然后設(shè)置相應(yīng)屬性值。由此可見,若某元素的某個(gè)屬性未重設(shè)值則保留原值,若原來(lái)Map或List 已有多個(gè)元素,也只會(huì)改變到 Key 或索引所對(duì)應(yīng)元素的某個(gè)屬性。對(duì)于 List 有可能出現(xiàn)跳空的情況,如頁(yè)面只有索引不從 0 開始
             <s:textfield name="users[1].name" label="第二個(gè)用戶名"/>
            <s:textfield name="users[1].name" label="第二個(gè)密碼"/>
    提交后就會(huì)發(fā)現(xiàn),List 屬性 users 的第一個(gè)元素為 null 了。同時(shí)如果嘗試一下,你就會(huì)發(fā)現(xiàn)這里的 List 不能替代為數(shù)組 User[] users。 
        這種樣法,可在 Struts 1 中實(shí)現(xiàn),但要略施些小節(jié),見我的另一篇日志:提交多行數(shù)據(jù)到Struts的ActionForm的List屬性中 ,行為表現(xiàn)完全一致,只是換到 Struts 2 中一切都不用自己操心。

    6. 看第四點(diǎn),Action 之所以知道該構(gòu)造什么類型的元素完全是由泛型告訴它的。如果不用泛型(比如用的是 JDK1.4),Action 中僅僅聲明的是 Map users; 或 List users; Action 該如何處理呢?它也不知道,只能夠幫你構(gòu)造出無(wú)類型的 HashMap 和 ArrayList(),填充不了元素。這就必須在局部類型轉(zhuǎn)換的配置文件中來(lái)指定集合元素的類型。例如 Action 為 LoginAction,就要在 LoginAction-conversion.properties 中聲明了,格式如下:

        #Element_xxx=復(fù)合類型,基中 Element 是固定的,xxx 為屬性名
        #下面表示為 List 屬性 users 的元素為 com.unmi.vo.User 類型
         Element_users=com.unmi.vo.User

        對(duì)于 Map,須分別指定 Key 的類型和 Value 的類型
        #Key_xxx=復(fù)合類型,基中 Key 是固定的,xxx 為 map 屬性名,下面寫成 String 都不行的
        Key_users=java.lang.String
        指定 Map 的 Value 的類型與指定 List 元素類型是一樣的
        Element_users=com.unmi.vo.User

    難 怪 Struts 2 要與 1.5 以上 JDK  使用,泛型比配置來(lái)得方便。如果硬要用 1.4 JDK,就只有配置類型了,會(huì)多很多 conversion 文件的。在 提交多行數(shù)據(jù)到Struts的ActionForm的List屬性中 中類型的確定由 AutoArrayList() 的構(gòu)造參數(shù)完成。

    7. Set 是無(wú)序集合,所以無(wú)法像 List 那樣用數(shù)字下標(biāo)來(lái)訪問,幸好 Struts 2 可為其指定索引屬性。例如,LoginAction 聲明為 Set users; (這里好像用泛型只能省得了 Element_users 說(shuō)明,KeyProperty_users 少不了)。則需在 LoginAction-conversion.properties 中寫下:
        #指定 Set 的元素類型
        Element_users=com.unmi.vo.User

        #KeyProperty_集合屬性名=集合元素的索引屬性名,這里為 User 的 name 屬性
        KeyProperty_users=name

    此時(shí)提交頁(yè)面這么寫,最好提交前能根據(jù)輸入的用戶名自動(dòng)修動(dòng)輸入框的 name。
            用戶名: <input name="users('scott').name"/>
            密 碼: <input name="users('scott').pass"/>
    顯示的時(shí)候頁(yè)面可用標(biāo)簽
            用戶名: <s:property value="users('scott').name"/>
            密 碼: <s:property value="users('scott').pass"/>
    注意前面,訪問 Set 元素是用的圓括號(hào),而不同于 Map、List、數(shù)組是用中括號(hào)。我想一般也犯不著非要用 Set 而不用 List,Struts 2 中用 Set 比在 Struts 1 中似乎還麻煩。

    8. Struts 2 內(nèi)建了一批轉(zhuǎn)換器:boolean、char、int、long、float、double 和它們的包裝類型;Date,日期格式使用請(qǐng)求所在 Locale 的 SHORT 格式;數(shù)組,默認(rèn)元素為字符串,其他類型則要轉(zhuǎn)換每一個(gè)元素?(好像是一次性轉(zhuǎn)換完成的); 集合,默認(rèn)元素為字符串 XWorkList(String.class, Object[]),其他如 List<Integer> ids,類型為 XWorkList(Integer.class, Object[]),XWorkList 繼承自 ArrayList。

    9. 類型轉(zhuǎn)換出錯(cuò)由 Struts 來(lái)幫你處理,在默認(rèn)攔截器棧中提供了 conversionError 攔截器,不用你寫一點(diǎn)代碼邏輯。conversionError 在出錯(cuò)時(shí)將錯(cuò)誤封裝成 fieldError,并放在 ActionContext 中。你所要做的就是遵循它的規(guī)則,1) 你的 Action 要繼承自 ActionSupport,2)在 struts.xml 中聲明名為 "input" 的 result,出錯(cuò)時(shí)會(huì)在 input 邏輯視圖顯示信息。3)盡量用標(biāo)簽來(lái)寫輸入域(如<s:textfield name="number" label="數(shù)量"/>),這樣轉(zhuǎn)換出錯(cuò)后,就會(huì)像校驗(yàn)失敗一樣把錯(cuò)誤信息顯示在每個(gè)輸入框上面(視模板而定),否則要手工用 <s:fielderror/> 輸出在某處。
    默認(rèn)時(shí)輸出錯(cuò)誤信息為(比如是屬性 number,輸入的是字符串時(shí)):Invalid field value for field "number".你可以改變默認(rèn)顯示,在全局國(guó)際化資源文件中加上 xwork.default.invalid.fieldvalue={0}字段類型轉(zhuǎn)換失敗!。在某些時(shí)候,可能還需要對(duì)特定字段指定特別的提示信息,那么在名為 ActionName.properties 的局部資源文件中加上 invalid.fieldvalue.屬性名=提示信息 (如 invalid.fieldvalue.number=數(shù)量格式錯(cuò)誤)

    10. 最后是集合屬性轉(zhuǎn)換錯(cuò)誤時(shí)的顯示,對(duì)于頁(yè)面中的同名輸入框,有多個(gè)出錯(cuò)誤,如果手工用 <s:fieldError/> 只會(huì)顯示一條錯(cuò)誤,但要是輸入頁(yè)是用標(biāo)簽(如<s:textfield name="number" label="數(shù)量"/>),仍會(huì)在每一個(gè)出錯(cuò)的輸入框上都提示。至此類型轉(zhuǎn)換的內(nèi)容也就完結(jié)了。

    相關(guān)文章:

    struts2的struts.xml配置中namespace的使用


    posted on 2008-12-26 21:11 墻頭草 閱讀(810) 評(píng)論(0)  編輯  收藏

    只有注冊(cè)用戶登錄后才能發(fā)表評(píng)論。


    網(wǎng)站導(dǎo)航:
     
    人人游戲網(wǎng) 軟件開發(fā)網(wǎng) 貨運(yùn)專家
    主站蜘蛛池模板: 99久久国产热无码精品免费| 国产精品1024在线永久免费| 免费一级毛片无毒不卡| 亚洲精品专区在线观看| 亚洲.国产.欧美一区二区三区| 99在线精品视频观看免费| 亚洲欧洲春色校园另类小说| 无码成A毛片免费| 亚洲精品**中文毛片| 成人电影在线免费观看| 亚洲国产精品无码久久一区二区| 成人免费乱码大片A毛片| 亚洲精品夜夜夜妓女网| 免费一级不卡毛片| 99久久婷婷国产综合亚洲| 在线观看免费宅男视频| 亚洲日韩中文字幕一区| 亚洲无人区码一二三码区别图片| 99久久久精品免费观看国产| 亚洲午夜国产精品| 猫咪社区免费资源在线观看| 久久精品亚洲日本波多野结衣 | 999国内精品永久免费视频| 亚洲人成日本在线观看| 国产成人免费爽爽爽视频| 亚洲AV第一成肉网| 国产成人综合亚洲AV第一页| 免费无遮挡无码永久视频| 亚洲一区在线视频| 免费一级大黄特色大片| 国产日韩精品无码区免费专区国产| 少妇高潮太爽了在线观看免费| 亚洲综合无码一区二区痴汉| 亚洲国产V高清在线观看| 免费黄网站在线看| 亚洲av无码片在线观看| 亚洲?V无码成人精品区日韩| 91福利视频免费观看| 国产成人精品亚洲一区| 亚洲国产天堂在线观看| 免费亚洲视频在线观看|