隨筆 - 72  文章 - 28  trackbacks - 0
          <2014年1月>
          2930311234
          567891011
          12131415161718
          19202122232425
          2627282930311
          2345678

          常用鏈接

          留言簿(4)

          隨筆分類(66)

          隨筆檔案(72)

          文章檔案(19)

          收藏夾

          搜索

          •  

          最新評論

          閱讀排行榜

          評論排行榜

          理解ActionContext ValueStack Stack Context
          ActionContext
          一次Action調用都會創建一個ActionContext
          調用:ActionContext context = ActionContext.getContext()

          ValueStack
          OGNL框架實現
          可以把它簡單的看作一個棧(List

          Stack Object:放入stack中的對象,一般是action
          Stack Contextmap):stack上下文,它包含一系列對象,包括request/session/attr/application map等。
          EL:存取對象的任意屬性,調用對象的方法,遍歷整個對象結…

          ActionContextAction上下文,可以得到request session application
          ValueStack是值棧 存放表單中的值
          Stack Context 棧上下文 也是用來存值的



          struts2OGNL上下文的概念又做了進一步擴充,在struts2中,OGNL上下文通常如下所示:

          |--request 



          |--application 



          context map---|--OgnlValueStack(root) [ user, action, OgnlUtil, ... ] 



          |--session 



          |--attr 



          |--parameters




          Struts2中,采用標準命名的上下文(Context)來處理OGNL表達式。處理OGNL的頂級對象是一個Map(也叫context map),而OGNL在這個context中就是一個頂級對象(root)。在用法上,頂級對象的屬性訪問,是不需要任何標記前綴的。而其它非頂級的對象訪問,需要使用#標記。
          Struts2框架把OGNL Context設置為我們的ActionContext。并且ValueStack作為OGNL的根對象。除value stack之外,Struts2框架還把代表applicationsessionrequest這些對象的Map對象也放到ActionContext中去。(這也就是Struts2建議在Action類中不要直接訪問Servlet API的原因,他可以通過ActionContext對象來部分代替這些(Servlet API)功能,以方便對Action類進行測試!)
          Action的實例,總是放到value stack中。因為Action放在stack中,而stackroot(根對象),所以對Action中的屬性的訪問就可以省略#標記。但是,要訪問ActionContext中其它對象的屬性,就必須要帶上#標記,以便讓OGNL知道,不是從根對象,而是從其它對象中去尋找。
          那么訪問Action中的屬性的代碼就可以這樣寫

          <s:property value="postalCode"/>
          其它ActionContext中的非根對象屬性的訪問要像下面這樣寫:
          <s:property value="#session.mySessionPropKey"/> or
          <s:property value="#session['mySessionPropKey']"/> or
          <s:property value="#request['myRequestPropKey']"/>
          Collection的處理,內容就很簡單。
          <s:select label="label" name="name" list="{'name1','name2','name3'}" value="%{'name2'}" />
          這是處理List。這個代碼在頁面上建立一個下拉選項,內容是list中的內容,默認值是name2.
          處理map

          <s:select label="label" name="name" list="#{'foo':'foovalue', 'bar':'barvalue'}" />

          需要注意的是,判斷一個值是否在collection中。我們要使用in或者not in來處理。
          <s:if test="'foo' in {'foo','bar'}">
          muhahaha
          </s:if>
          <s:else>
          boo
          </s:else>
          另外,可以使用通配符來選擇collection對象的子集。
          ?——所有匹配選擇邏輯的元素
          ^——只提取符合選擇邏輯的第一個元素
          $——只提取符合選擇邏輯的最后一個元素
          person.relatives.{? #this.gender == 'male'}

          ?

          ?

          值棧(ValueStack) 
          Struts2OGNL上下文設置為Struts2中的ActionContext(內部使用的仍然是OgnlContext),并將值棧設為OGNL的根對象。 
          我們知道,OGNL上下文中的根對象可以直接訪問,不需要使用任何特殊的“標記”,而引用上下文中的其他對象則需要使用“#”來標記。由于值棧是上下文中的根對象,因此可以直接訪問。那么對于值棧中的對象該如何訪問呢?Struts2提供了一個特殊的OGNLPropertyAccessor,它可以自動查找棧內的所有對象(從棧頂到棧底),直接找到一個具有你所查找的屬性的對象。也就是說,對于值棧中的任何對象都可以直接訪問,而不需要使用“#”。 
          假設值棧中有兩個對象:studentemployee,兩個對象都有name屬性,student有學號屬性number,而employee有薪水屬性salaryemployee先入棧,student后入棧,位于棧頂,那么對于表達式name,訪問的就是studentname屬性,因為student對象位于棧頂;表達式salary,訪問的就是employeesalary屬性。正如你所見,訪問值棧中的對象屬性或方法,無須指明對象,也不用“#”,就好像值棧中的對象都是OGNL上下文中的根對象一樣。這就是Struts2OGNL基礎上做出的改進。

           值棧中的Action實例 
          Struts2框架總是把Action實例放在棧頂。因為Action在值棧中,而值棧又是OGNL中的根,所以引用Action的屬性可以省略“#”標記,這也是為什么我們在結果頁面中可以直接訪問Action的屬性的原因。

           Struts2中的命名對象 
          Struts2還提供了一些命名對象,這些對象沒有保存在值棧中,而是保存在ActionContext中,因此訪問這些對象需要使用“#”標記。這些命名對象都是Map類型。 

          parameters 
          用于訪問請求參數。如:#parameters['id']#parameters.id,相當于調用了HttpServletRequest對象的getParameter()方法。 
          注意,parameters本質上是一個使用HttpServletRequest對象中的請求參數構造的Map對象,一量對象被創建(在調用Action實例之前就已經創建好了),它和HttpServletRequest對象就沒有了任何關系。 

          request 
          用于訪問請求屬性。如:#request['user']#request.user,相當于調用了HttpServletRequest對象的getAttribute()方法。 

          session 
          用于訪問session屬性。如:#session['user']#session.user,相當于調用了HttpSession對象的getAttribute()方法。 

          application 
          用于訪問application屬性。如:#application['user']#application.user,相當于調用了ServletContextgetAttribute()方法。 

          attr 
          如果PageContext可用,則訪問PageContext,否則依次搜索requestsessionapplication對象。

          假設你的Action類中有變量String password; 要想獲取頁面中傳過來的password,必須為password設置get 和set 方法。當你的頁面進入Action時,ActionContext(Action上下文)通過set方法獲取password的值并壓入值棧棧頂,同時request也獲取到password的值,同時也如堆棧,session等對象的值也被壓入堆棧,ActionContext中的值在頁面中可以直接用<s:porperty value="password">取值顯示,而request中存儲的password通過<s:porperty value="#request.password">或者${password}取值。即struts是通過一個值棧來存儲所有對象和ActionContext中的值得。ActionContext為棧頂對象,也稱跟對象,ActionContext的值可以直接用變量名取,而其他的變量需要用#變量名取值。


          posted on 2014-01-09 11:20 kelly 閱讀(480) 評論(0)  編輯  收藏 所屬分類: java 框架
          主站蜘蛛池模板: 白山市| 吉首市| 万州区| 千阳县| 吐鲁番市| 文水县| 察雅县| 河津市| 威远县| 西安市| 长子县| 苏尼特左旗| 福海县| 姜堰市| 兴宁市| 江川县| 合江县| 遂川县| 缙云县| 台安县| 桃园县| 南溪县| 石城县| 大同县| 班戈县| 顺昌县| 奎屯市| 龙口市| 和田县| 东乡族自治县| 宝山区| 澄城县| 崇明县| 揭西县| 托克逊县| 白山市| 龙江县| 黄山市| 五莲县| 湛江市| 仪陇县|