程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 編程語言 >> JAVA編程 >> 關於JAVA >> Unmi的Struts2學習筆記(九)

Unmi的Struts2學習筆記(九)

編輯:關於JAVA

中世紀的歐洲《禮儀書》中說:痰不要吐到桌子上,也不要飛過桌子。1774年 ,歐洲的《禮儀與基督教禮貌守則》中說:我們再也不能原諒那些把痰吐到窗戶 外、牆上或者家具上的人。可見,歐洲人的素質也是在他們工業化富了之後的事 。至少那個時候,我們的老祖宗再不爭氣,也絕不會把痰吐到桌子上。

1. OGNL 中有生成 List 和 Map 的表達式,分別是:{e1,e2,e3,...} 和 # {key1:val1,key2:val2,...}。對集合 OGNL 提供了兩個操作符 in 和 not in, 如:

<s:if test="'foo' in {'foo','bar'}" ... </s:if>       ---- not in 的用法當然是一樣的了。

之外,OGNL 還允許通過某個規則取集合的子集

·? :取出所有符合條件邏輯的元素

·^:取出符合條件的第一個元素

·$:取出符合條件的最後一個元素

請將上面這三個符號與正則表達式的表示法聯系起來

例了:persons.relatives.{? #this.gender == 'male'}    //取出集合 persons 中所有 gender 屬性為 'male' 的子集。

OGNL 還支持基本的 Lambda(λ) 表達式語法,不過好像有點復雜,暫不關顧 。

2. Struts2 的各路標簽已是面目全非了。

<s:if test="exp">...</s:if><s:elseif test="exp">...</s:elseif><s:else>...</s:else> 對應 了 java 的 if/else if/else

<s:iterator.../> value 未指定是默認為 ValueStack 棧頂集合。id 為當前元素變量名。status 為 IteratorStatus 實例,包含奇還是偶行,當前索 引,是否第一或最後一條記錄。

3. iterator 可以迭代 List、Set 和數組,也可以迭代 Map,用法如下:

<s:iterator value="{'e1','e2','e3'}" id="name" status="st">

  //這是用 OGNL 生成的 List
     <s:property value="name"/>      //也可以寫成 <s:property value="#name"/>
      <s:if test="#st.odd">偶數位 </s:if>
      // st 其他屬必如:#st.count、#st.index、 #st.even、#st.first、#st.last,前面的 # 號不能少
   </s:iterator>

迭代 Map,用 key 和 map 對應

<s:iterator value="#

{'key1':'val1','key2':'val2','key3':'val3'}">
    <s:property value="key"/> | <s:property value="value"/>  //不能寫成 #key 和 #value,對 OGNL 還不熟
  </s:iterator>

4. <s:append.../> 用於將多個集合拼成一個新集合,從而能用一個 <s:iterator .../> 對多個集合迭代,也能拼 Map 的。<s:merge .../> 也是用來拼接集合,只是不像 <s:append .../> 那樣依次保持 著順序,<s:merge .../> 是交錯的。可以理解為前一個是深度拼接,後一 個是廣度拼接。

5. 在學習 <s:generator .../> 時我們能同時體驗一下 Struts2 標簽 是如何操作棧的,當然這裡指的是 ValueStack,而非 Java 的方法棧。

<s:generator val="'1,2,3'" separator=","> <!--字符

串'123'以","分隔生成一個集合,並壓棧-->
     <s:iterator>   <!-- 這裡沒有指定 value 屬性,默認彈棧,並取一個元素壓棧 -->       
      <s:property/> <!-- 也沒有指定 value 屬性,默認也是取棧頂元素 -->
     </s:iterator>   <!-- 迭代完成則從集合遍歷的最後一個元素出棧 -->
  </s:generator>   <!-- 最後,自動出棧, generator 生成的集合出棧 -->

匯編是基於寄存器操作的,而 Java 是基於棧的操作,Struts2 引入了存放在 request 中的 ValueStack 正好完美再現了 Java 的這一原始本性,並可使標簽 使用更簡潔,靈活。Struts2 還有很多標簽也有這個特性:

1) 生成的新實例,壓棧,標簽結束後自動出棧

2) 在未指定數據來源時,默認從棧頂取數據。

不禁回想起 Struts1 的 <nested:root> 等 nested 標簽要顯示的聲明 操作的根元素,是多麼麻煩的一件事。

補充:如果指定了 <s:generator .../> 的 id 屬性的話,同時還會把 生成的集合放到 pageContext 中,key 就是 id 指定的值。

6. <s:subset .../> 是用來取集合子集的,可從 source (未指定則為 棧頂集合) 集合的 start 位置起取 count 個元素。或者按自定義的 decider 條 件,取符合條件的子集。你的 decider 要實現 SubsetIteratorFilter.Decider 接口的 decide(object element) 方法,符合條件的返回 true。此處不列出具體 用法的實例。

7. <s:sort .../> 依據 comparator 指定的比較器,對 source (未指 定則為棧頂集合) 集合排序。排序頭的集合當然也是壓入棧中,標簽結束自動出 棧。

8. <s:debug/> 會在頁面生成一個 debug 鏈接,展開能看到 ValueStack 和 Stack Context 中的內容,該頁面有顯示用 #key 能獲取到 Stack Context 中的值。<s:property .../> 在前面用很多次了,就相當 於 Struts1 的 <bean:write .../>,value 未指定,輸出棧頂值;若要 輸出的值為 null 時,指定了 default 屬性則輸出它;escape 指定是否忽略 HTML 代碼,同 <bean:write .../> 的 ignore 屬性。

9. <s:push .../> 用於將某個值壓棧,標簽結束後自動出棧,可方便 某些操作,Struts1 的 <nested:root> 有類似功能。<s:set .../> 標簽用於把某個值放入指定范圍內,用 scope 指定,如 application、session 、request、page、action。若未指定 scope 則放到 Stack Context 中;name 為新變量名;value 為欲處理的變量,未指定則取棧頂值。

10. 從前面的標簽,你也許已經注意到,Struts2 常操作的幾個數據結構有 ValueStack、pageContext 和 StackContext。例如:generator、sort、subset 等生成的新實例會壓到棧頂,並在標簽結束自動出棧;如果 sort、subset 未指 定 source 源集合,則從棧頂取,iterator、property 也是一樣的;若為 generator 指定了 id 屬性,則生的集合會存到 pageContext 中,key 就是 id 對應值;如果為 bean 指定了 id 屬性,則會把 bean 實例存入到 Stack Context 中,key 就是 id 對應值,Stack Conext 中的值可以用 #key 取得。其 他標簽類似的地方應該要注意到。

最後再來一貼,理解 ValueStack 和 Stack Context:

1) ValueStack 可以用 request.getAttribute("struts.valueStack") 取得 的一個 com.opensymphony.xwork2.util.OgnlValueStack 實例,它實現為一個棧 ,有 peek()、pop()、push(obj) 方法。

2) Stack Context 是在前面的 ValueStack 的上下中的一個 java.util.Stack 實例:

//stack 為 ValueStack 實例,COMPONENT_STACK="__component_stack"
  // org.apache.struts2.components.Component.getComponentStack() 中的代碼   Stack componentStack = (Stack) stack.getContext().get(COMPONENT_STACK);
  1. 上一頁:
  2. 下一頁:
Copyright © 程式師世界 All Rights Reserved