一、ValueStack(值栈):
贯穿整个Action周期,每一个Action类的对象实例都有一个ValueStack对象,相当于一个数据的中转站,在其中保存当前Action对象和其它相关对象。
在值栈中有两个逻辑部分:①ContextMap;②ObjectStack
①ContextMap:Struts把各种各样的映射关系(一些Map类型对象)压入ContextMap中,实际上是对ActionContext的一个引用。Struts会把以下Map压入ContextMap:
-parameter该Map中包含当前请求的请求参数
-request该Map中包含request对象的所有属性
-session该Map中包含session对象的所有属性
-application该Map中包含application对象的所有属性
-attr该Map中按照request——>session——>application的顺序来检索某个属性
②ObjectStack:把Action实例和相关对象压入ObjectStack。这是一个继承了ArrayList的一个类,实际上是一个CompoundRoot类型,是一个标准的数
据结构意义上的先进后出的栈结构。
ps. EL表达式 ${xxx}并不是从当前request等域对象中获得,而是从值栈中获取的一个值。
Struts2利用<s:property>标签和OGNL表达式来读取栈中的属性值。
1、ObjectStack里的对象的属性:
object.propertyName
object['propertyName']
object["propertyName"] 三种方法均可。
通常,用[0]表示对栈顶的引用。且需要注意的是[n]表示从第n个开始搜索,并不是只搜索第n个对象。
格式: <s:property value="object.propertyName" />
ps.Action对象会被struts2框架最先放在栈顶
2、ContextMap里的对象
#object.propertyName
#object['propertyName']
#object["propertyName"] 三种方法均可。
eg:<s:property value="#session.objectName.propertyName"/>
注意这里访问的是ActionContext,即Action 的上下文。JavaBean对象是放入这个映射集合中而不是值栈中,所以在取值时要加上“#”,表示从映射集合
中取值。
那么,OGNL还可以用来获取什么样的对象呢?
3、Java类里的静态字段或方法 & 被压入到ValueStack栈中对象的公共字段和方法。
默认情况下,Struts2不允许访问Java类静态方法,需要设置一下:在struts.xml中加入:
<struts>
<constant name="struts.ognl.allowStaticMethodAccess" value="true"></constant>
<package name="struts_demo" namespace="/demo" extends="struts-default">
<action name="login" class="cn.wqy.LoginAction">
<result name="success">/loginsuc.jsp</result>
<result name="error">/loginfal.jsp</result>
</action>
</package>
</struts>
调用Java类里的静态字段或方法: @Java类全名@静态字段或方法
调用压入到ValueStack栈中对象的公共字段和方法: object.fieldName & object.methodName(arguementList)
4、访问数组类型的属性
<%
String [] names = new String[]{"a","b","c"};
request.setAttribute("names", names);
%>
<body>
<br>
<s:property value="#request.names.length"/>
</body>
5、访问List类型的属性
同 数组类型
访问List中元素的某个属性的集合:object.{propertyName}
访问List中元素的某个属性的特定值:object.{propertyName}.[index]
6、访问Map类型的属性
基本同 数组类型。
<s:property value="#attr.mapName.size" />
<s:property value="#attr.mapName[keyName]" />
访问Map中全部的key:mapName.keys
访问Map中全部的value:mapName.values
7、? ^ $操作符与投影过滤操作
?:表示取出符合条件的所有值
eg:<s:property value="users.{?#this.age==1}.{age}" /> 取出users中所有的对象中属性age为1的对象的age属性
^:表示取出符合条件的值列表的第一个值
eg:<s:property value="users.{^#this.age>1}" />取出users中所有的对象中属性age大于1的值的第一个对象
$:表示取出符合条件的值列表的最后一个值
8、%符号
struts2中使用%表示字符串,%{xxx}表示内部是ognl表达式,是需要解析的。
总结:EL能用的肯定能用OGNL,能用OGNL的不一定能用EL。