应用:ValueStack
理解ValueStack的基本机制!对各种现象作出解释。
ValueStack实际上就是对OGNL的封装,OGNL主要的功能就是赋值与取值,Struts2正是通过ValueStack来进行赋值与取值的!
ValueStack是一个接口,而OgnlValueStack是strtus2中的缺省实现。ValueStack中的数据,分两个部分存放:root和context(这与OGNL中的概念一致),同时ValueStack暴露相关的接口:
void setValue(String expr, Object value);
Object findValue(String expr);
用来通过OGNL表达式对ValueStack中的数据进行操作!
值栈就是一个List.
ValueStack中的root对象是CompoundRoot,CompoundRoot继承了ArraryList,提供了额外的方法:push()和pop()方法,用来对root对象中所包含的数据进行存取!
|
public class CompoundRoot extends ArrayList { public CompoundRoot() { } public CompoundRoot(List list) { super(list); } public CompoundRoot cutStack(int index) { return new CompoundRoot(subList(index, size())); } public Object peek() { return get(0); } public Object pop() { return remove(0); } public void push(Object o) { add(0, o); } } |
正是通过这两个方法,CompoundRoot变成了一个栈结构!压栈操作,将导致对象被放到CompoundRoot的第0个元素上(第0个元素是栈顶),其它对象被依次往后移动;出栈操作,将导致CompoundRoot的第0个元素被移除(即栈顶元素被弹出),其它对象被依次往前移动!
OGNL不支持多个root对象,而struts2能够支持多个root对象,它对OGNL做了扩展。
如果某个OGNL表达式被传递给ValueStack(即调用ValueStack的setValue或findValue方法),而表达式中包含有对root对象的访问操作,ValueStack将依次从栈顶往栈底搜索CompoundRoot对象中所包含的对象,看哪个对象具有相应的属性,找到之后,立刻返回。
在Struts2中,一个请求在最终到达Action的方法之前,Action对象本身会被压入ValueStack(实际上就是放到ValueStack的CompoundRoot中),所以Action对象是CompoundRoot中的一个元素。看下面的代码:
|
public class UserAction { private String username; private Integer age; private boolean valid; //查看用户的详细信息 public String detail(){ username = "张三"; age = 18; valid = true; return "detail"; } |
在Action中,给Action的username/age/valid赋值。Detail页面如下:
|
username:<s:property value="username"/> <br/> valid:<s:property value="valid"/> <br/> age:<s:property value="age"/> <br/> |
上述JSP页面将能正确将它们的值取出。<s:property value=”ognl表达式”/>。在s:property标签中的OGNL表达式,最终会交给ValueStack来解释。username就是一个OGNL表达式,意思是调用root对象的getUsername()方法。Struts2将自动搜索CompoundRoot中有哪些元素(从第0个元素开始搜索),检测这些元素是否有getUsername()方法,如果第0个元素没有getUsername()方法,将继续搜索第1、2、3……个元素是否有getUsername()方法。
在上面的例子中,CompoundRoot中只有一个对象,就是userAction对象,而这个对象中正好有getUsername()方法,所以,上述JSP代码将能够将值正确取出。
再看下面的例子:
|
public class UserAction { private String username; private String name; //查看用户的详细信息 public String detail(){ username = "张三"; name = "王五"; User u = new User(); u.setUsername("赵毅"); ActionContext.getContext().getValueStack().push(u); return "detail"; } |
在上面这个UserAction的代码中,我们直接调用ActionContext.getContext().getValueStack().push()方法,把一个User对象(这个对象拥有getUsername()和setUsername()方法)直接压入到ValueStack中,这时候,在ValueStack的CompoundRoot中将有两个元素:第0个元素是刚刚压入的user对象[赵毅],而第1个元素是userAction对象[张三],如果在JSP中使用下面的表达式来取值:
<s:property value=”username”/> ,那么输出的值将是“赵毅”!道理上面已经讲过了,struts2将会从第0个元素开始搜索CompoundRoot中的对象,第0个元素正是刚刚压入的那个user对象!
如果在JSP中使用<s:property value=”name”/>来取值,将取出“王五”,因为第0个元素user对象没有name属性,所以,会继续搜索第1个元素userAction对象,在这个对象中就有name属性了!
再看下面的代码:
|
public class UserAction { private String username; //查看用户的详细信息 public String detail(){ username = "张三"; List list = new ArrayList(); for(int i=0; i<10; i++){ User user = new User(); user.setUsername("User"+i); list.add(user); } ActionContext.getContext().put("users", list); User u = new User(); u.setUsername("赵毅"); ActionContext.getContext().getValueStack().push(u); return "detail"; } |
对应的JSP如下:
|
1: <s:property value="username"/> <br/> 2: <s:iterator value="#users"> 3: <s:property value="username"/> 4: <s:property value="#root[2].username"/><br/> 5: </s:iterator> 6: <s:property value="username"/> 7: <s:property value="#root[1].username"/> <!-- 张三 --> |
根据刚才的示例,我们知道,第1行的username是“赵毅”(因为JSP在执行这行代码的时候,CompoundRoot中有两个元素:第0个是“user对象赵毅”,第1个是“userAction对象张三”),因此第1行的username将取出CompoundRoot中第0个元素的username属性:赵毅
第2行代码是iterator标签,只定义了一个value属性,iterator标签将循环访问users这个List中的User对象,并把当前循环的user对象压入到CompoundRoot中!所以,在第3行和第4行代码被执行的时候,CompoundRoot中总共有3个元素:第0个元素是被iterator标签压入的当前循环的user对象;第1个元素是“user对象赵毅”;第2个元素是“userAction对象张三”,因此第3行代码的执行结果就是输出“UserX”,即当前循环的user对象的username属性!iterator标签将会依次取出List中的user对象,并不断压入/弹出user对象(每次循环,都将执行一遍压入/弹出)。而第4行代码取第2个元素的username属性,即userAction对象的username属性:张三。
第5行代码执行完成之后,在CompoundRoot中将剩下2个元素,与第2行代码被执行之前一样。所以,第6行代码的输出和第1行代码的输出结果是一样的,而第7行代码将取出userAction对象的username属性:张三
应用:ValueStack的更多相关文章
- 4. ValueStack 和 OGNL
1. 属性哪来的 当我们通过Action处理完用户请求以后,可以直接在页面中获取到 action 的属性值. 如果我们在页面中尝试遍历四个域中的属性,会发现域中并没有username之类的Action ...
- [转] valuestack,stackContext,ActionContext.之间的关系
三者之间的关系如下图所示: ActionContext 一次Action调用都会创建一个ActionContext 调用:ActionContext context = ActionContext ...
- 什么是ValueStack
转载自:http://www.cnblogs.com/zyw-205520/archive/2012/09/12/2681346.html Strut2的Action类通过属性可以获得所有相关的值,如 ...
- [转]Struts2数据传输的背后机制:ValueStack(值栈)
1. 数据传输背后机制:ValueStack(值栈) 在这一切的背后,是因为有了ValueStack(值栈)! 2. ValueStack基础:OGNL 要了解ValueStack,必须先理解OGNL ...
- OGNL和ValueStack
OGNL简介 OGNL的全称是Object Graph Navigation Language,即对象导航图语言.它是一个开源项目,工作在视图层,其通过简单一致的表达式语言来读取合适者Java对象的属 ...
- OGNl和ValueStack的基础和深入分析
一.OGNL 1)什么是OGNL? 解析:OGNL是Object Graph Navigation Language(对象图导航语言)它是强大的表达式语言. 2)用途:通过简单一致的表达式语法来读取和 ...
- valuestack,stackContext,ActionContext.之间的关系以及如何存取数值的
2013-03-15 10:54 1722人阅读 评论(1) 收藏 举报 分类: J2EE 版权声明:本文为博主原创文章,未经博主允许不得转载. 三者之间的关系如下图所示: ActionCont ...
- Struts 中 ActionContext ctx.put()把数据放到ValueStack里之数据传输背后机制:ValueStack(值栈)
1. 数据传输背后机制:ValueStack(值栈) 在这一切的背后,是因为有了ValueStack(值栈)! ValueStack基础:OGNL要了解ValueStack,必须先理解OGNL ...
- struts2重点——ValueStack和OGNL
一.值栈(ValueStack) 1.实现类:OGNLValueStack 2.对象栈:CompoundRoot(针对的是类级别的) (1)继承自 ArrayList —— 先进后出 (2)提供了栈的 ...
- struts2中valueStack,stackContext以及actionContext的关系
一,首先给出三者的定义 1.valueStack: 里面存放的是Action类中通过set方法设置的属性值(表单传过来的值等),由OGNL框架实现; 2.stackContext: 也是用来存值的,s ...
随机推荐
- 弹出框页面中使用jquery.validate验证控件
弹出框页面中使用jquery.validate验证控件有几个问题需要解决: 1,弹出框的提交事件完成后如何关闭弹出框页面? 2,提交不成功如何返回当前页? 3,如果知道验证事件成功? 之前笔者都是JS ...
- UVa 294 (因数的个数) Divisors
题意: 求区间[L, U]的正因数的个数. 分析: 有这样一条公式,将n分解为,则n的正因数的个数为 事先打好素数表,按照上面的公式统计出最大值即可. #include <cstdio> ...
- I.MX6 android 移除shutdown功能
/************************************************************************ * I.MX6 android 移除shutdown ...
- Android Service即四大组件总结
原文转载自:http://www.cnblogs.com/bravestarrhu/archive/2012/05/02/2479461.html Service 服务: 一个Service 是一段长 ...
- 55人班37人进清华北大的金牌教师之32条教育建言! z
他带的一个55人的班,37人考进清华.北大,10人进入剑桥大学.耶鲁大学.牛津大学等世界名校并获全额奖学金,其他考入复旦.南开等大学.不仅 如此,校足球冠军.校运动会总冠军.校网页设计大赛总冠军等6项 ...
- 那些年一起踩过的坑 — Date类型序列化的问题
坑在哪里? 序列化 和 反序列化 的时候对Date字段的格式设置不一致 例如:将Java bean序列化成Json string的时候 格式为 yyyy-MM-dd 解 ...
- ASP.Net MVC_DotNetZip简单使用方法,解决文件压缩的问题[转]
准备工作: 在vs工具栏中找到NuGet 下载DotNetZip 现在就可以使用DotNetZip强大的类库了,在这里我给出一些简单的使用. ? 1 2 3 4 5 6 7 8 9 10 11 ...
- C#打印100以内质数
bool b = false; ; i < ; i++) { ; j < i; j++) { ) { b = false; break; } else { b = true; } } if ...
- iOS7适配之设计篇
(注:文章简要翻译自 Apple <iOS 7 UI Transition Guide>,由于该文档为开发者预览版,并非最终文档,所以 iOS7 正式上线可能有部分不同) 准备工作 iOS ...
- Code First 更新数据库结构(简单实现方法:会删除原来的数据)
之前在 http://www.cnblogs.com/mmcmmc/p/3833265.html 写到关于“Code First 更新数据库结构”的东西. 可是由于某种原因,新手们会出现各种问题,好了 ...