OGNL是Object-Graph Navigation Language的缩写,它是一种功能强大的表达式语言,通过它简单一致的表达式语法,可以存取对象的任意属性,调用对象的方法,遍历整个对象的结构图,实现字段类型转化等功能。它使用相同的表达式去存取对象的属性。
通过值栈(ValueStack)debug 跟踪StrutsRequestWrapper 的 getAttribute() 方法, 当传入参数 为“productName” 时, ActionContext 对象的即时状态如下:
•在 ValueStack 对象的内部有两个逻辑部分:
(一)值栈介绍:
•在 ValueStack 对象的内部有两个逻辑部分:
–ObjectStack: Struts 把 Action 和相关对象压入 ObjectStack 中
–ContextMap: Struts 把各种各样的映射关系(一些Map 类型的对象) 压入 ContextMap 中. 实际上就
是对ActionContext 的一个引用
•Struts会把下面这些映射压入 ContextMap 中
–parameters:该 Map 中包含当前请求的请求参数
–request:该 Map 中包含当前request 对象中的所有属性
–session:该 Map 中包含当前session 对象中的所有属性
–application:该 Map中包含当前 application 对象中的所有属性
–attr: 该 Map 按如下顺序来检索某个属性: request, session, application
•在 JSP 页面上可以可以利用OGNL(Object-GraphNavigation Language: 对象-图导航语言) 访问到值栈 (ValueStack) 里的对象属性.
•若希望访问值栈中ContextMap中的数据,需要给 OGNL 表达式加上一个前缀字符 #.如果没有前缀字符 #, 搜 索将在ObjectStack里进行.
OGNL相关标签
Struts的 property 标签用来输出值栈中的一个属性值
读取ObjectStack 里的对象的属性
•若想访问 ObjectStack 里的某个对象的属性. 可以使用以下几种形式之一:
•
ObjectStack
里的对象可以通过一个从零开始的下标来引用
. ObjectStack 里的栈顶对象可以用[0] 来引
用, 它下面的那个对象可以用 [1] 引用. 若希望返回栈顶对象的message 属性值: [0].message 或
[0][“message”]或 [0][‘message’]
•
若在指定的对象里没有找到指定的属性
,
则到指定对象的下一个对象里继续搜索
.
即
[n]
的含义是从第
n
个开始搜索
,
而不是只搜索第
n
个对象
•
若从栈顶对象开始搜索
,
则可以省略下标部分
读取Context Map 里的对象的属性
•若想访问ContextMap 里的某个对象的属性, 可以使用以下几种形式之一:
•示例:
–返回session 中的 code属性: #session.code
–返回request 中的 customer属性的 name 属性值: #request.customer.name
–返回域对象(按 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 是 ObjectStack 栈里的某个对象的引用:
–
.
object.fieldName: [0].datePattern
–
.
object.methodName
(
argumentList
):[0].repeat(3, “Hello”);
访问数组类型的属性
•有些属性将返回一个对象数组而不是单个对象, 可以像读取任何其他对象属性那样读取它们. 这种
数组型属性的各个元素以逗号分隔
,
并且不带方括号
•可以使用
下标访问数组中指定的元素: colors[0]
•可以通过调用其length 字段查出给定数组中有多少个元素:
colors.length
访问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 的值, 需要使用如下格式:
map[key]
•可以使用size 或 size()得出某个给定的 Map 的键值对的个数
•可以使用isEmpty 或 isEmpty()检查某给定 Map 是不是空.
•可以使用如下语法来创建一个Map:
•<s:propertyvalue=“fieldName”> 也
可以通过
JSP EL
来达到目的: ${fieldName}
原理: Struts2 将包装 HttpServletRequest 对象后的org.apache.struts2.dispatcher.StrutsRequestWrapper对象传到页面上, 而这个类重写了getAttribute() 方法.
(三)通用标签
①:property标签用来输出一个值栈属性的值
•示例:
–输出Action 属性 customerId 的值: <s:propertyvalue=“customerId”/>
–输出session 属性 userName 的值: <s:property value=“#session.userName”/>
•
如果
value
属性没有给出
,
ValueStack
值栈栈顶对象的值被输出
•
在许多情况下
, JSP EL
可以提供更简洁的语法
②:
url 标签用来动态地创建一个URL
③: param 标签用来把一个参数传递给包含着它的那个标签
•无论在给出value 值时有没有使用 %{},
Struts
都会对它进行
ognl
求值
•如果想传递一个String 类型的字符串作为参数值, 必须把它用
单引号括起来.
•可以把value 属性的值写在开始标签和结束标签之间.
利用这种方式来传递一个
EL
表达式的值
④:
set标签用来在以下 Map 对象里创建一个键值对:
–ValueStack 值栈的ContextMap 值栈
–Map类型的 session 对象
–Map类型的 application 对象
–Map类型的 request 对象
–Map类型的 page 对象
⑤:
push标签的功能和 set 标签类似.
•push标签将把一个对象
压入
ValueStack 而不是压入ContextMap.
•push标签
在标签起始时把一个对象压入栈
,
标签结束时将对象弹出栈.
⑥:
if,else
和
elseif
标签
这三个标签用来进行条件测试, 它们的用途和用法类似于if, else 和 elseif 关键字. 其中if 和 elseif 必须有test 属性
⑦:
•iterator 标签用来遍历一个数组, Collection 或一个 Map,
并把这个可遍历对象里的每一个元素
依次压入和弹出
ValueStack
栈
•在开始执行时, iterator 标签会先把IteratorStatus 类的一个实例压入ContextMap, 并在每次遍历循环时
更新它. 可以将一个指向IteratorStatus 对象的变量赋给status 属性.
•iterator标签的 status 属性的属性值
⑧:
sort
标签用来对一个可遍历对象里的元素进行排序
⑨:date标签用来对 Date 对象进行排版
•format属性的值必须是 java.text.SimpleDateFormat 类里定义的日期/时间格式之一.
还有几个不常用的可以借助官方文档查看
下篇我将讲述Struts2的表单标签和ModelDriven 和 Preparable 拦截器