Struts2-值栈和OGNL

1:值栈
ValueStack(值栈): 贯穿整个 Action 的生命周期(每个 Action 类的对象实例都拥有一个 ValueStack 对象). 相当于一个数据的中转站. 
在其中保存当前 Action 对象和其他相关对象. 
Struts 框架把 ValueStack 对象保存在名为 "struts.valueStack"" 的请求属性中

页面读取属性并不是在request域中 获取,而是通过值栈获取
值栈可以分为两个逻辑部分,
>Map栈:ContextMap,实际上是OgnlContext类型。是一个Map,也是对ActionContext的一个引用;里边保存着各种Map,
RequestMap,sessionMap,applicationMap,paramtersMap,attr
>对象栈:实际上是CompoundRoot类型,是一个使用ArrayList定义的栈,里边保存着和当前action实例相关的对象;是一个数据结构意义的栈
详细介绍:
在 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

2:OGNL
在 JSP 页面上可以可以利用 OGNL(Object-Graph Navigation Language: 对象-图导航语言) 访问到值栈(ValueStack) 里的对象属性.
若希望访问值栈中 ContextMap 中的数据, 需要给 OGNL 表达式加上一个前缀字符 #. 如果没有前缀字符 #, 搜索将在 ObjectStack 里进行. 
2.1 property 标签,Struts 的 property 标签用来输出值栈中的一个属性值. 
2.2 若想访问 Object Stack 里的某个对象的属性. 可以使用以下几种形式之一: 
ObjectStack 里的对象可以通过一个从零开始的下标来引用. ObjectStack 里的栈顶对象可以用 [0] 来引用, 它下面的那个对象可以用 [1] 引用. 
若希望返回栈顶对象的 message 属性值:  [0].message 或 [0][“message”] 或 [0][‘message’]
若在指定的对象里没有找到指定的属性, 则到指定对象的下一个对象里继续搜索. 即 [n] 的含义是从第 n 个开始搜索, 而不是只搜索第 n 个对象
若从栈顶对象开始搜索, 则可以省略下标部分
//获取值栈,
        ValueStack valueStack = ActionContext.getContext().getValueStack();
        //创建Test对象,并为其属性赋值
        Test object = new Test();
        object.setProductDesc("AAA");
        object.setProductPrice(11);
        //把Test对象,压入到值栈的栈顶;
        valueStack.push(object);
获取其属性:ProductPrice:<s:property value="[0].productPrice"/>

2.3读取 Context Map 里的对象的属性
若想访问 ContextMap 里的某个对象的属性, 可以使用length:<s:property value="#attr.names.length"/>
示例:
返回 session 中的 code 属性: #session.code
返回 request 中的 customer 属性的 name 属性值: #request.customer.name
返回域对象(按 request, session, application 的顺序)的 lastAccessDate 属性: #attr.lastAccessDate
继承 RequestAware , SessionAware,并设置属性
@Override
public void setSession(Map<String, Object> session)
{
// TODO Auto-generated method stub
this.session = session;
}

@Override
public void setRequest(Map<String, Object> request)
{
this.request = request;
}
session.put("product", this);
        request.put("Test", object);
获取属性:
<s:property value="#request.Test.productDesc"/>
<s:property value="#session.product.productDesc"/>
2.4调用字段和方法
可以利用 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");
示例:
<!-- ognl调用静态字段,静态方法 -->
<s:property value="@java.lang.Math@PI"/>
<s:property value="@java.lang.Math@cos(0)"/>
<!-- ognl调用值栈-对象栈的一个方法   并为该属性赋值 -->
<s:property value="setProductName('THT')"/>
2.5访问数组类型的属性,访问list和此基本相似
有些属性将返回一个对象数组而不是单个对象, 可以像读取任何其他对象属性那样读取它们. 这种数组型属性的各个元素以逗号分隔, 并且不带方括号
可以使用下标访问数组中指定的元素: colors[0]
可以通过调用其 length 字段查出给定数组中有多少个元素: colors.length
<!-- 调用数组对象的属性 -->
<%
String[] names = new String[]{"aa","bb","cc","dd"};
request.setAttribute("names",names);
%>
length:<s:property value="#attr.names.length"/>
<br>
names[2]:<s:property value="#attr.names[2]"/>
2.6访问 Map 类型的属性
若希望检索出某个 Map 的值, 需要使用如下格式: map[key] 
可以使用 size 或 size() 得出某个给定的 Map 的键值对的个数
可以使用 isEmpty 或 isEmpty() 检查某给定 Map 是不是空. 
案例:
<!-- 使用ognl访问map -->
<br><br>
<%
Map<String,String> letters = new HashMap<String,String>();
request.setAttribute("letters",letters);
letters.put("AA","aa");
letters.put("BB","bb");
letters.put("CC","cc");
%>
<s:property value="#attr.letters.size"/>
<s:property value="#attr.letters['AA']"/>
最后说一点也可以使用 EL 访问值栈中对象的属性
比如<s:property value=“fieldName”> 也可以通过 JSP EL 来达到目的: ${fieldName}


  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值