想要了解OGNL,首先要搞清楚ValueStack(值栈)的概念。如下图所示,value即所谓ValueStack对象。
可以看出,ValueStack分为两个逻辑部分
- Map栈。实际上是 OgnlContext 类型,是个 Map,也是对 ActionContext 的一个引用.。里边保存着各种 Map:requestMap, sessionMap, applicationMap, parametersMap, attr
- 对象栈。实际上是CompoundRoot类型,是一个ArrayList定义的栈。很多情况下,我们所说的ValueStack就是指的对象栈
即如下图所示
访问对象栈中的元素
- 可以使用以下几种形式之一:
- object.propertyName
- object['propertyName']
- object["propertyName"]
推荐使用第一种,看起来简单,而且javaWeb大多对象时javaBean。
- ObjectStack 里的对象可以通过一个从零开始的下标来引用。ObjectStack 里的栈顶对象可以用 [0] 来引用,它下面的那个对象可以用 [1] 引用。
- [n] 的含义是从第 n 个开始搜索,而不是只搜索第 n 个对象。
- 若从栈顶对象开始搜索, 则可以省略下标部分。
访问Map栈中元素
需要加前缀字符#,没有前缀,将在ObjectStack中查找。
结合例子
TestAction接收来自页面提交过来的Student对象,利用ModelDriven(这个会将Student对象压如栈顶,一般情况下,默认将Action压入栈顶)
public class TestAction extends ActionSupport implements ModelDriven<Student>{
private Student student = new Student();
public String save(){
ValueStack valueStack = ActionContext.getContext().getValueStack();
Test test = new Test();
test.setName("test");
test.setAge(12);
valueStack.push(test);
return "save";
}
public Student getModel() {
return this.student;
}
}
save方法中获取ValueStack对象,同时将Test对象压入栈顶
所以ValueStack中的顺序就会是这个样子,Test对象在栈顶,Student对象次之,然后是Action
下面第一步是通过name来获取,那么他将会从栈顶对象开始寻找,Test满足。
第二步从第二个对象向后找,student对象满足。
第三步获取Map栈中的对象,通过前缀字符#完成。
第四步,访问类的静态资源或方法,如果是方法,需要在struts2的配置文件中配置(allowStaticMehod...)。
<s:debug/>
<!-- 获取栈顶元素属性 -->
<s:property value="name"/> <br>
<!-- 获取从当前位置往后找 -->
<s:property value="[1].teacherName"/> <br>
<% request.setAttribute("name","---->"); %>
<!-- 获取Map域中的元素 -->
<s:property value="#request.name"/> <br>
<!-- 获取静态元素或方法 -->
<s:property value="@java.lang.Math@PI"/>
最后结果如下
<img src="https://img-blog.csdn.net/20150811211353384?watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQv/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/Center" alt="" />