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

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

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

    posts - 78, comments - 34, trackbacks - 0, articles - 1
      BlogJava :: 首頁(yè) :: 新隨筆 :: 聯(lián)系 :: 聚合  :: 管理

    Struts2第二天,大家似乎沒有從年假中蘇醒過來,上課顯得有些疲憊。不過還好,聽課效果還不錯(cuò)。今日的主要內(nèi)容是OGNLStruts2使用OGNL訪問contextMapvalueStack。老張很執(zhí)著,他在研究Struts2時(shí)遇到的一些問題,一定要解決,并且要詳細(xì)解決。通過他在講課中,我們可以看出這一點(diǎn)。有開發(fā)經(jīng)驗(yàn)的人都知道,我們時(shí)而被陌生技術(shù)的一個(gè)小細(xì)節(jié)搞的暈頭轉(zhuǎn)向,耗費(fèi)了大半天的時(shí)間我們才發(fā)現(xiàn)這個(gè)細(xì)節(jié)性的錯(cuò)誤。我們一般都是這么熬出來的,老張也不例外。


    我們?cè)诼犂蠋熤v課時(shí)或在網(wǎng)上看視頻時(shí),都感覺學(xué)習(xí)起來十分容易。卻很少有人能感受那些認(rèn)真負(fù)責(zé)老師在課后付出的心血。老張為了準(zhǔn)備一天的課程內(nèi)容,使用了三天時(shí)間來備課并且課程內(nèi)容他以前也講過。這一點(diǎn)不僅體現(xiàn)在老張的身上,其他老師也是這樣。讓我們?yōu)槟切┱J(rèn)真負(fù)責(zé)的老師敬禮,并問候一聲:“過年好,您辛苦了!”。


    一、ActionContext

    Action環(huán)境(com.opensymphony.xwork2.ActionContext),通過我們之前所學(xué)的內(nèi)容。我們知道Context緩存中保存了XXX環(huán)境中所需要使用到的重要對(duì)象。Struts2中的ActionContext中就保存了Struts2中使用到的重點(diǎn)對(duì)象contextMapvalueStack


    老張搞了一個(gè)經(jīng)典的關(guān)系圖:


    ActionContext ac = ActionContext.getContext();

    ValueStack vs = ac.getValueStack();

    Map<String, Object> conMap = ac.getContextMap();

    每一個(gè)訪問線程具有一個(gè)ActionContext對(duì)象,它是以單例模式存在的。ActionContext為我們提供了操作valueStackcontextMap的便捷方法。例我們的程序可以與ValueStackContextMap解耦,比如:ac.put(key, value);ac.get(key);...


    通過ActionContext使得我們編寫的Action不必實(shí)現(xiàn)任何接口和繼承任何超類,但我們必須在類中使用ActionContext的實(shí)例。


    二、Struts2中的OGNL

    OGNL不是Struts2獨(dú)創(chuàng)的,而是Struts2中使用OGNL做為操作contextMapvalueStack的方式。OGNLObject-Graph Navigation Language的縮寫,它是一種功能強(qiáng)大的表達(dá)式語(yǔ)言(Expression Language,簡(jiǎn)稱為EL),通過它簡(jiǎn)單一致的表達(dá)式語(yǔ)法,可以存取對(duì)象的任意屬性,調(diào)用對(duì)象的方法,遍歷整個(gè)對(duì)象的結(jié)構(gòu)圖,實(shí)現(xiàn)字段類型轉(zhuǎn)化等功能。它使用相同的表達(dá)式去存取對(duì)象的屬性。


    OGNLl基本的語(yǔ)法:

    1. 可以用#key的形式訪問OGNL Context對(duì)象中的各個(gè)key對(duì)應(yīng)的對(duì)象,并可以采用點(diǎn)(.)操作符進(jìn)行多級(jí)導(dǎo)航調(diào)用對(duì)象的屬性和方法,例如,#application#session.attr1#key1.sayHello();對(duì)于map對(duì)象,map.attr不是map.getAttr()方法,而是表示map.get(“attr1”)

    2. 如果要訪問根對(duì)象的屬性或方法,則可以省略#key,直接訪問該對(duì)象的屬性和方法。 struts2修改了OGNL表達(dá)式的默認(rèn)屬性訪問器,它不是直接訪問根對(duì)象ValueStack的屬性或方法,而是在ValueStack內(nèi)部的堆棧中所有對(duì)象上逐一查找該屬性或方法,搜索順序是從棧頂對(duì)象開始尋找,依次往下,直到找到為止,例如,sayHello()表示調(diào)用堆棧中某個(gè)對(duì)象的sayHello()方法。

    3. 特例:如果引用名前面沒有#,且valueStack中存儲(chǔ)的各個(gè)對(duì)象沒有該屬性,則把該名稱當(dāng)作Context對(duì)象中的某個(gè)key來檢索對(duì)應(yīng)的對(duì)象,但這種方式不支持點(diǎn)(.)操作符。


    ValueStack提供了如下一些方法管理其內(nèi)部的堆棧和關(guān)聯(lián)的Context

    1. setValueognl表達(dá)式尋址到的對(duì)象設(shè)置屬性值。

    2. FindValue方法使用OGNL表達(dá)式獲取結(jié)果。

    3. findString方法對(duì)findValue方法獲取的結(jié)果調(diào)用轉(zhuǎn)換器轉(zhuǎn)成字符串,如果該對(duì)象的類型沒有相關(guān)轉(zhuǎn)換器,則調(diào)用toString方法,并返回結(jié)果字符串。一個(gè)特殊之處:如果不用#前綴訪問ValueStack Context中的對(duì)象,則該對(duì)象必須是String類型。


    三、Struts2中的struts-tagsOGNL詳細(xì)

    要使用struts-tags標(biāo)簽,必須先引入struts-2.1.7.dtd文檔類型定義文件。

    1. <s:property>用于輸出某個(gè)OGNL表達(dá)式的值,可以認(rèn)為其內(nèi)部使用的是ValueStack對(duì)象的findString方法。如果沒有設(shè)置value屬性,則輸出ValueStack棧頂?shù)膶?duì)象。

      特例:如果采用不加#前綴的方式輸出Context中的某個(gè)對(duì)象,這個(gè)對(duì)象必須是string類型。

      如:獲取contextMap中的request對(duì)象。

      <s:property value="#request" />

    2. <s:push>用于將OGNL表達(dá)式的值壓入棧頂,當(dāng)遇到</s:push>標(biāo)簽時(shí),從棧頂彈出。

      如:向棧頂壓入了一個(gè)字符串——“你好!”。

      <s:push value="'你好!'">

      <s:property value="top" />

      </s:push>

      注意壓入的字符串必須被包含在''中,否則會(huì)被OGNL當(dāng)做名稱到根對(duì)象中查找相應(yīng)的值。

      通過查看<s:push>標(biāo)簽的幫助,可以知道有一個(gè)為top的特殊OGNL表達(dá)式,表示棧頂?shù)膶?duì)象。

      如:

    <s:push value="'你好!'"><s:property name="top"/></s:push>


    1. <s:bean>用于實(shí)例化一個(gè)JavaBean對(duì)象,并將其壓入棧頂。如果設(shè)置了var屬性,還會(huì)將實(shí)例化的對(duì)象存儲(chǔ)進(jìn)ValueStack關(guān)聯(lián)的Context中。

      如:實(shí)例化一個(gè)java.util.Date對(duì)象,然后將其放入ContextMap中。

      <s:bean name="java.util.Date" var="MyBean">

      <s:property value="#MyBean" />

      </s:bean>

    2. <s:set>用于將某個(gè)值存入指定范圍域中,通常用于將一個(gè)復(fù)雜的ognl表達(dá)式用一個(gè)簡(jiǎn)單的變量來進(jìn)行引用。

      如:向request域中添加一個(gè)名稱為“TestSet”的屬性。

      <s:set scope="request" value="'日期'+#MyBean" name="TestSet">

      <s:property value="#request.TestSet" />

      </s:set>

      scope屬性:指定變量被放置的范圍,該屬性可以接受applicationsessionrequest pageaction。該屬性的默認(rèn)值為action,文檔說即表示同時(shí)存儲(chǔ)進(jìn)request作用域和OGNL Context中,但實(shí)驗(yàn)結(jié)果是只存儲(chǔ)進(jìn)了OGNL Context中。

      value屬性:賦給變量的ognl表達(dá)式結(jié)果.如果沒有設(shè)置該屬性,則將ValueStack棧頂?shù)闹蒂x給變量。

    3. <s:if/elseif/else>等標(biāo)簽用于判斷test屬性中指定的ognl表達(dá)式的結(jié)果是否為true,為真則執(zhí)行標(biāo)簽體重的內(nèi)容。

      如:設(shè)置一個(gè)VAL,然后判斷VAL的值,并顯示相應(yīng)的結(jié)果。

      <s:set value="'1'" name="VAL"></s:set>

      <s:if test="1 > 2">

      <s:property value="#VAL+'>2'" />

      </s:if>

      <s:elseif test="1 < 2">

      <s:property value="#VAL+'<2'" />

      </s:elseif>

      <s:else>

      <s:property value="#VAL+'=2'" />

      </s:else>

    4. <s:iterator>用于迭代一個(gè)OGNL集合,并逐一將迭代出來的元素壓入棧頂和彈棧。

      如:獲取request中的所有屬性,并且使表格奇數(shù)行顏色為#f3c3c3,偶數(shù)行顏色為#c3f3f3

      <table>

      <tr>

      <td>Key</td><td>Value</td>

      </tr>

      <s:iterator value="#request" status="status">

      <tr bgcolor='<s:property value="#status.odd ? '#f3c3c3':'#c3f3f3'"/>' >

      <td><s:property value="key"/></td>

      <td><s:property value="value"/></td>

      </tr>

      </s:iterator>

      </table>

      status屬性:創(chuàng)建代表當(dāng)前迭代狀態(tài)的IteratorStatus對(duì)象,并指定將其存儲(chǔ)進(jìn)ValueStack Context中時(shí)的key。它與官方給出的幫助文檔的說明不同,官方存在錯(cuò)誤!

    5. <s:url><s:a>

      使用這兩個(gè)標(biāo)簽可以帶給我們極大的方便,使用他們的好處有:

      使用<s:url namespace=“” action=“” method=“”/>不用關(guān)心web應(yīng)用程序的路徑和Action映射的擴(kuò)展名。<s:url>中沒有指定namespace屬性時(shí),將根據(jù)瀏覽器當(dāng)前所訪問的url地址來推測(cè)包名,并與action屬性指定的內(nèi)容一起生成最終的url地址。

      可以自動(dòng)附加jsessionid參數(shù)進(jìn)行url重寫。

      可以對(duì)參數(shù)信息進(jìn)行url編碼。 (jstl中的<c:url>標(biāo)準(zhǔn)標(biāo)簽也有<s:url>標(biāo)簽的后兩個(gè)作用。)

      直接使用<s:url />標(biāo)簽可以獲得當(dāng)前地址,只有使用includeParams屬性會(huì)帶上原來的請(qǐng)求參數(shù)。大型網(wǎng)站的鏈接地址總是要帶上userid之類的信息。

      如:生成一個(gè)訪問我們昨天編寫的HelloWorld請(qǐng)求超連接。

      <s:a namespace="/" action="helloWorld" method="helloWorld">HelloWorld</s:a>

    四、OGNL中的語(yǔ)法細(xì)節(jié)

    1.參看ognl的參考手冊(cè)

    類似EL表達(dá)式的JavaBean屬性訪問和索引訪問,例如,可以用”#parameter.id[0]”或”#parameter[‘id’][0]”訪問名稱為id的請(qǐng)求參數(shù)。

    支持類靜態(tài)方法調(diào)用和屬性訪問,表達(dá)式的格式為@[類全名(包括包路徑)]@[方法名 | 值名],例如:@java.lang.String@format(‘foo %s’, ‘bar’)@cn.itcast.Constant@APP_NAME

    session.attribute[“foo”]等效于session.getAttribute(“foo”)方法。

    OGNL中可以寫很大的整數(shù),例如,<s:property value="%{1111111111111111111111H.bitLength()}"/>,而在java中則不能直接寫1111111111111111111111這么大的整數(shù)。

    對(duì)當(dāng)前值可以進(jìn)一步操作,<s:property value=“110H.intValue().(#this<112?#this*2:#this/2)”/>,其中.(#this …..)部分相當(dāng)于定義了一個(gè)匿名方法,并調(diào)用這個(gè)匿名方法,方法的代碼就是()里面的內(nèi)容。


    2.Struts2擴(kuò)展的特殊功能

    [n]表示從原來堆棧中截取一個(gè)子堆棧并對(duì)這個(gè)子堆棧進(jìn)行操作,子堆棧為原始堆棧的棧頂開始的索引號(hào)為n的元素一直到棧底,例如,[1].age表示從原始堆棧中的索引號(hào)為1的對(duì)象(即第二個(gè)對(duì)象)開始查找age屬性,以找到的第一個(gè)為準(zhǔn)。

    top表示ValueStack棧頂?shù)膶?duì)象,[0].toptop表示同一個(gè)對(duì)象。


    3.集合對(duì)象與操作

    {}用于創(chuàng)建List集合對(duì)象,其中的各個(gè)元素之間用逗號(hào)分隔:

    <s:set value="{1,3,5,7}" var="list"/>


    采用類似Java的語(yǔ)法創(chuàng)建數(shù)組:

    <s:set value="new int[]{1,3,5,7}" var="array"/>

    <s:set value="new int[4]" var="array"/>

    #{}用于創(chuàng)建Map集合對(duì)象,其中的各個(gè)元素之間用逗號(hào)分隔,元素的keyvalue之間采用冒號(hào)分隔。另外,還可以指定Map實(shí)例對(duì)象的類型:

    <s:set value="#{'lhm':96,'zxx':93,'xpc':97}" />

    <s:set value="#@java.util.LinkedHashMap@{'lhm':96,'zxx':93,'xpc':97}" />

    innot in操作符用于判斷某個(gè)值是否位于某個(gè)集合中。

    <s:set value="new int[]{1,3,5,7}" var="array"/>

    <s:if test="1 in #array">

    <s:property value="#array"/>

    </s:if>

    集合偽屬性:size/isEmpty/iterator/keys/values/next/hasNext

    <s:set value="#{'lhm':96,'zxx':93,'xpc':97}" var="map"/>

    <s:if test="#map.size > 0">

    <s:property value="#map"/>

    </s:if>


    4.集合的投影與過濾

    投影就是拿著集合中的每個(gè)元素去進(jìn)行運(yùn)算,各個(gè)元素運(yùn)算的結(jié)果組成一個(gè)新集合,新集合中的元素個(gè)數(shù)與原始集合中的元素個(gè)數(shù)相同。

    <s:property value="persons.{name}"/>

    <s:property value="{5,3,2}.{#this*2}"/>

    過濾就是拿著集合中的每個(gè)元素去進(jìn)行布爾運(yùn)算,運(yùn)算的結(jié)果為true,則將該元素保存到新集合中去。

    ?:獲得所有符合邏輯的元素。

    <s:property value="{5,3,2,0}.{? #this }"/>

    ^:獲得符合邏輯的第一個(gè)元素。

    <s:property value="{5,3,2,0}.{^ #this>3 }"/>

    $:獲得符合邏輯的最后一個(gè)元素。

    <s:property value="{5,3,2,0}.{$ #this>2 }"/>


    5.類型轉(zhuǎn)換

    轉(zhuǎn)換成boolean類型:

    • 整數(shù)0轉(zhuǎn)換為fals

    • 值為0的字符轉(zhuǎn)化為false

    • Null對(duì)象轉(zhuǎn)化為false

    投影和選擇操作符(e1.{e2} and e1.{?e2})里面的內(nèi)容會(huì)被轉(zhuǎn)換成集合

    Map會(huì)被轉(zhuǎn)化成其values屬性返回的集合

    數(shù)字會(huì)被轉(zhuǎn)換成從0開始到比該數(shù)字小1的所有數(shù)字的集合。

    單個(gè)對(duì)象被轉(zhuǎn)換成僅僅只含有該對(duì)象的集合。


    五、在配置文件中使用OGNL

    在下堂課中會(huì)做總結(jié)!



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


    網(wǎng)站導(dǎo)航:
     
    主站蜘蛛池模板: 男女交性无遮挡免费视频| 亚洲午夜国产片在线观看| 性xxxxx免费视频播放| 无码人妻AV免费一区二区三区| 巨胸狂喷奶水视频www网站免费| 一边摸一边桶一边脱免费视频| 无套内谢孕妇毛片免费看看| 美女视频黄.免费网址| 国产亚洲精品2021自在线| 老司机午夜在线视频免费观| 羞羞漫画页面免费入口欢迎你| 男女超爽视频免费播放| 思思久久99热免费精品6| jizz在线免费播放| 中文字幕视频在线免费观看| 国产午夜无码精品免费看| 国产精品区免费视频| 99在线免费观看视频| 日日麻批免费40分钟日本的| 免费不卡视频一卡二卡| 大学生美女毛片免费视频| 国产精品久久香蕉免费播放| 免费人成无码大片在线观看| 国产精品亚洲精品日韩已方| 亚洲av无码专区在线播放| 亚洲美女一区二区三区| jiz zz在亚洲| 免费人成大片在线观看播放| 两个人的视频www免费| 伊人久久免费视频| 成年人免费观看视频网站| 免费又黄又爽又猛的毛片| 亚洲精品国产字幕久久不卡| 亚洲综合视频在线观看| 亚洲欧美不卡高清在线| 乱爱性全过程免费视频| 久久久久免费精品国产小说| 日本一区二区三区免费高清| 免费人成无码大片在线观看| 亚洲成a人片在线观看中文动漫| 亚洲一区二区三区深夜天堂|