Unmi的Struts2学习笔记(九)

中世纪的欧洲《礼仪书》中说:痰不要吐到桌子上,也不要飞过桌子。1774年 ,欧洲的《礼仪与基督教礼貌守则》中说:我们再也不能原谅那些把痰吐到窗户 外、墙上或者家具上的人。可见,欧洲人的素质也是在他们工业化富了之后的事 。至少那个时候,我们的老祖宗再不争气,也绝不会把痰吐到桌子上。

1. OGNL 中有生成 List 和 Map 的表达式,分别是:{e1,e2,e3,…} 和 # {key1:val1,key2:val2,…}。对集合 OGNL 提供了两个操作符 in 和 not in, 如:

<s:if test="'foo' in {'foo','bar'}" …        —- not in 的用法当然是一样的了。

之外,OGNL 还允许通过某个规则取集合的子集

·? :取出所有符合条件逻辑的元素

·^:取出符合条件的第一个元素

·$:取出符合条件的最后一个元素

请将上面这三个符号与正则表达式的表示法联系起来

例了:persons.relatives.{? #this.gender == ‘male’}    //取出集合 persons 中所有 gender 属性为 ‘male’ 的子集。

OGNL 还支持基本的 Lambda(λ) 表达式语法,不过好像有点复杂,暂不关顾 。

2. Struts2 的各路标签已是面目全非了。

对应 了 java 的 if/else if/else

value 未指定是默认为 ValueStack 栈顶集合。id 为当前元素变量名。status 为 IteraTorStatus 实例,包含奇还是偶行,当前索 引,是否第一或最后一条记录。

3. iteraTor 可以迭代 List、Set 和数组,也可以迭代 Map,用法如下:

<s:iteraTor value="{'e1','e2','e3'}" id="name" status="st">  //这是用 OGNL 生成的 List<br />     <s:property value="name"/>      //也可以写成 <s:property value="#name"/><br />      <s:if test="#st.odd">偶数位</s:if><br />      // st 其他属必如:#st.count、#st.index、#st.even、#st.first、#st.last,前面的 # 号不能少<br />  </s:iteraTor>

迭代 Map,用 key 和 map 对应

<s:iteraTor value="#{'key1':'val1','key2':'val2','key3':'val3'}"><br />   <s:property value="key"/> | <s:property value="value"/>  //不能写成 #key 和 #value,对 OGNL 还不熟<br />  </s:iteraTor>

4. 用于将多个集合拼成一个新集合,从而能用一个 对多个集合迭代,也能拼 Map 的。 也是用来拼接集合,只是不像 那样依次保持 着顺序, 是交错的。可以理解为前一个是深度拼接,后一 个是广度拼接。

5. 在学习 时我们能同时体验一下 Struts2 标签 是如何操作栈的,当然这里指的是 ValueStack,而非 Java 的方法栈。

<s:generaTor val="'1,2,3'" separaTor=","> <!--字符串'123'以","分隔生成一个集合,并压栈--><br />    <s:iteraTor>   <!-- 这里没有指定 value 属性,默认弹栈,并取一个元素压栈 -->       <br />      <s:property/> <!-- 也没有指定 value 属性,默认也是取栈顶元素 --><br />    </s:iteraTor>   <!-- 迭代完成则从集合遍历的最后一个元素出栈 --><br />  </s:generaTor>   <!-- 最后,自动出栈,generaTor 生成的集合出栈 -->

汇编是基于寄存器操作的,而 Java 是基于栈的操作,Struts2 引入了存放在 request 中的 ValueStack 正好完美再现了 Java 的这一原始本性,并可使标签 使用更简洁,灵活。Struts2 还有很多标签也有这个特性:

1) 生成的新实例,压栈,标签结束后自动出栈

2) 在未指定数据来源时,默认从栈顶取数据。

不禁回想起 Struts1 的 等 nested 标签要显示的声明 操作的根元素,是多么麻烦的一件事。

补充:如果指定了 的 id 属性的话,同时还会把 生成的集合放到 pageContext 中,key 就是 id 指定的值。

6. 是用来取集合子集的,可从 source (未指定则为 栈顶集合) 集合的 start 位置起取 count 个元素。或者按自定义的 decider 条 件,取符合条件的子集。你的 decider 要实现 SubsetIteraTorFilter.Decider 接口的 decide(object element) 方法,符合条件的返回 true。此处不列出具体 用法的实例。

7. 依据 comparaTor 指定的比较器,对 source (未指 定则为栈顶集合) 集合排序。排序头的集合当然也是压入栈中,标签结束自动出 栈。

8. 会在页面生成一个 debug 链接,展开能看到 ValueStack 和 Stack Context 中的内容,该页面有显示用 #key 能获取到 Stack Context 中的值。 在前面用很多次了,就相当 于 Struts1 的 ,value 未指定,输出栈顶值;若要 输出的值为 null 时,指定了 default 属性则输出它;escape 指定是否忽略 HTML 代码,同 的 ignore 属性。

9. 用于将某个值压栈,标签结束后自动出栈,可方便 某些操作,Struts1 的 有类似功能。 标签用于把某个值放入指定范围内,用 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"<br />  // org.apache.struts2.components.Component.getComponentStack() 中的代码  Stack componentStack = (Stack) stack.getContext().get(COMPONENT_STACK);

不会因为别人显赫的成功而促使自己有卓越的进步。

Unmi的Struts2学习笔记(九)

相关文章:

你感兴趣的文章:

标签云: