值栈
- 可以从值栈中获取栈对象
使用${productName}获取值,实际上该属性并不在request等域对象中,而是从值栈中获取的。 值栈分为两部分
Map栈:实际上是OgnlContext类型,是个Map,也是对ActionContext的一个引用。里面保存着各种Map:requestMap,sessionMap,applicationMap,paramtersMap,attr;
- parameters: 该 Map 中包含当前请求的请求参数
- request: 该 Map 中包含当前 request 对象中的所有属性
- session: 该 Map 中包含当前 session 对象中的所有属性
- application:该 Map 中包含当前 application 对象中的所有属性
- attr: 该 Map 按如下顺序来检索某个属性: request, session, application
对象栈:实际上是CompoundRoot类型,是一个使用ArrayList定义的栈。里面保存各种和当前Action实例相关的对象。是一个数据结构任意的对象。
OGNL
在 JSP 页面上可以可以利用 OGNL(Object-Graph Navigation Language: 对象-图导航语言) 访问到值栈(ValueStack) 里的对象属性.
若希望访问值栈中 ContextMap 中的数据, 需要给 OGNL 表达式加上一个前缀字符 #. 如果没有前缀字符 #
, 搜索将在 ObjectStack 里进行.
property 标签
Struts 的 property 标签用来输出值栈中的一个属性值.
读取 ObjectStack 里的对象的属性
- 若想访问
ObjectStack
里的某个对象的属性. 可以使用以下几种形式之一:
object.propertyName
object['propertyName']
object["propertyName"]
ObjectStack
里的对象可以通过一个从零开始的下标来引用.ObjectStack
里的栈顶对象可以用[0]
来引用, 它下面的那个对象可以用[1]
引用. 若希望返回栈顶对象的message
属性值:[0].message
或[0]["message"]
或[0]['message']
- 若在指定的对象里没有找到指定的属性, 则到指定对象的下一个对象里继续搜索. 即
[n]
的含义是从第 n 个开始搜索, 而不是只搜索第 n 个对象 - 若从栈顶对象开始搜索, 则可以省略下标部分
读取 Context Map 里的对象的属性
若想访问 ContextMap 里的某个对象的属性, 可以使用以下几种形式之一:
#object.propertyName
#object['propertyName']
#object["propertyName"]
示例:
1. 返回 session
中的 code
属性: #session.code
2. 返回 request
中的 customer
属性的 name
属性值: #request.customer.name
3. 返回域对象(按 request, session, application
的顺序)的 lastAccessDate
属性: #attr.lastAccessDate
调用字段和方法
- 可以利用
OGNL
调用
- 任何一个
Java
类里的静态字段或方法. - 被压入到
ValueStack
栈的对象上的公共字段和方法.
- 任何一个
- 默认情况下,
Struts2
不允许调用任意Java
类静态方法, 需要重新设置struts.ognl.allowStaticMethodAccess
标记变量的值为true
. - 调用静态字段或方法需要使用如下所示的语法:
@fullyQualifiedClassName@fieldName
:@java.util.Calendar@DECEMBER
@fullyQualifiedClassName@methodName(argumentList)
:@app4.Util@now()
- 调用一个实例字段或方法的语法, 其中
object
是Object Stack
栈里的某个对象的引用:
.object.fieldName
:[0].datePattern
.object.methodName(argumentList)
:[0].repeat(3, “Hello”);
访问数组类型的属性
- 有些属性将返回一个对象数组而不是单个对象, 可以像读取任何其他对象属性那样读取它们. 这种数组型属性的各个元素以逗号分隔, 并且不带方括号
- 可以使用下标访问数组中指定的元素: colors[0]
- 可以通过调用其 length 字段查出给定数组中有多少个元素: colors.length
<s:property value="#attr.names.length"/>
<s:property value="#attr.names[2]"/>
访问 List 类型的属性
有些属性将返回的类型是 java.util.List, 可以像读取任何其他属性那样读取它们. 这种 List 的各个元素是字符串, 以逗号分隔, 并且带方括号
可以使用下标访问 List 中指定的元素: colors[0]
可以通过调用其 size 方法或专用关键字 size 的方法查出给定List 的长度: colors.size 或 colors.size()
可以通过使用 isEmpty() 方法或专用关键字 isEmpty 来得知给定的 List 是不是空. colors.isEmpty 或 colors.isEmpty()
还可以使用 OGNL 表达式来创建 List, 创建一个 List 与声明一个 Java 数组是相同的: {“Red”, “Black”, “Green”}
访问 Map 类型的属性
- 读取一个 Map 类型的属性将以如下所示的格式返回它所有的键值对:
{key-1=value-1, key-2=value-2,...,key-n=value-n}
- 若希望检索出某个 Map 的值, 需要使用如下格式:
map[key]
- 可以使用
size
或size()
得出某个给定的Map
的键值对的个数 - 可以使用
isEmpty
或isEmpty()
检查某给定Map
是不是空. - 可以使用如下语法来创建一个
Map
:
#{key-1=value-1, key-2=value-2,...,key-n=value-n}
使用 EL 访问值栈中对象的属性
<s:property value="fieldName">
也可以通过 JSP EL
来达到目的: ${fieldName}
原理: Struts2
将包装 HttpServletRequest
对象后的 org.apache.struts2.dispatcher.StrutsRequestWrapper
对象传到页面上, 而这个类重写了 getAttribute()
方法.
EL 能做的OGNL都能做,但是OGNL能做的,EL不一定能做。
<s:debug></s:debug>
<br/>
利用$ { name }获取<br/>
NAME:${name }<br/>
DESC:${desc }<br/>
PRICE:${price }<br/>
<br/>
获取字段和方法<br/>
PI:<s:property value="@java.lang.Math@PI"/><br/>
COS(0):<s:property value="@java.lang.Math@cos(0)"/><br/>
person.show():<s:property value="[0].show()"/>
<br/>
读取 ValueStack 里的对象的属性<br/>
DESC:<s:property value="[1].desc"/><br/>
<br/>
读取 Context Map 里的对象的属性<br/>
DESC:<s:property value="#session.person.desc"/><br/>
<%
String[] str = {"value","stack","object"};
request.setAttribute("str", str);
%>
<br/>
访问数组类型的属性<br/>
LENGHT:<s:property value="#request.str.length"/><br/>
OBJECT:<s:property value="#request.str[1]"/><br/>
<br/>
<br/>
访问Map类型的属性<br/>
LENGHT:<s:property value="#request.map.size()"/><br/>
isEmpty:<s:property value="#request.map.isEmpty()"/><br/>
OBJECT:<s:property value="#request.map.get('Liu')"/><br/>