OGNL valueStack StackContext(ActionContext)深入分析(转+个人理解)
//还会补充
首先要有一个意识 ,为什么要了解这个?:
struts2中的表单是怎么通过表达式(EL or OGNL)来传给Action 和 拿到Action的值的。
值栈(根)对象也可以直接使用EL表达式访问,比如这里可以直接通过${user.username}来获取username的值,我们知道el表达式只能访问四种scope范围内的对象,那为什么这里能访问到值栈对象呢?原因是struts2对HttpServletRequet进行了一次封装,封装的代码主要是重写了getAttribute方法,简述重写此方法的核心代码:首先在原始的HttpServletRequest对象中查找el表达式中的属性,如果找不到再通过ActionContext获取值栈对象,进而再从值栈对象中查找el表达式中要访问的属性。
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
当Struts2接收到一个.action的请求后,会先建立Action类的对象实例,但并不会调用Action方法,而是
①先将Action类的相应属性放到ValueStack对象的顶层节点(ValueStack对象相当于一个栈)。只是所有的属性值都是默认的值,如String类型的属性值为null,int类型的属性值为0等。处理完上述工作后,
②Struts2就会调用拦截器链中的拦截器,当调用完所有的拦截器后,最后会调用Action类的Action方法,在调用Action方法之前,会将
③ValueStack对象顶层节点中的属性值赋给Action类中相应的属性,注意,在这里就给我们呆了很大的灵活性。也就是说,在Struts2调用拦截器的过程中,可以改变ValueStack对象中属性的值,当改变某个属性之后,Action类的相应属性值就会变成在拦截器中最后改变该属性的这个值。(通过setValue方法可以改变)
1、值栈(ValueStack)
Struts2将OGNL上下文设置为Struts2中的ActionContext(内部使用的仍然是OgnlContext),并将值栈设为OGNL的根对象。valuestack是ONGL的跟对象
我们知道,OGNL上下文中的根对象(valuestack)可以直接访问,不需要使用任何特殊的“标记”,而引用上下文中的其他对象则需要使用“#”来标记。由于值栈是 上下文中的根对象,因此可以直接访问。那么对于值栈中的对象该如何访问呢?Struts2提供了一个特殊的OGNLPropertyAccessor,它 可以自动查找栈内的所有对象(从栈顶到栈底),直接找到一个具有你所查找的属性的对象。也就是说,对于值栈中的任何对象都可以直接访问,而不需要使用 “#”。
假设值栈中有两个对象:student和employee,两个对象都有name属性,student有学号属性number,而 employee有薪水属性salary。employee先入栈,student后入栈,位于栈顶,那么对于表达式name,访问的就是student 的name属性,因为student对象位于栈顶;表达式salary,访问的就是employee的salary属性。正如你所见,访问值栈中的对象属 性或方法,无须指明对象,也不用“#”,就好像值栈中的对象都是OGNL上下文中的根对象一样。这就是Struts2在OGNL基础上做出的改进。
2、[N]语法
如上所述,如果想要访问employee的name属性,应该如何写表达式呢?我们可以使用[N].xxx(N是从0开始的整数)这样的语法来指定从哪一个位置开始向下查找对象的属性,表达式[1].name访问的就是employee对象的name属性。
在使用[N].xxx语法时,要注意位置序号的含义,它并不是表示“获取栈中索引为N的对象”,而是截取从位置N开始的部分栈。
因为根栈结构是一个ArrayList,根据栈的数据结构,访问一个值是不断pop掉栈顶的值来做到访问该list的对象
4、访问静态成员
除了使用标准的OGNL表达式访问静态字段和静态方法(struts2从某版本开始需要在常量中注册struts.ognl.allowStaticMethodAccess 为true 才能调用静态方法)外,Struts2还允许你不指定完整的类名,而是通过“vs”前缀来调用保存在栈中的静态字段和静态方法。
@vs@FOO_PROPERTY
@vs@someMethod()
@vs1@someMethod()
<s: property value="@java.util.UUID@randomUUID()" />
vs表示ValueStack,如果只有vs,那么将使用栈顶对象的类;如果在vs后面跟上一个数字,那么将使用栈中指定位置处的对象类。
5、值栈中的Action实例
Struts2框架总是把Action实例放在栈顶。因为Action在值栈中,而值栈又是OGNL中的根,所以引用Action的属性可以省略“#”标记,这也是为什么我们在结果页面中可以直接访问Action的属性的原因。
个人总结:
1.首先拿到vs对象有三种方式在这里不说了, 查笔记
2.在actionContext(大Map)中有指向vs的key;而在vs中也有大map的Map<String,Object> getContext()应用 和 一个list;
3.综上所以vs 和 actionContext 构成了OGNL 访问数据的上下文!(一个大map结构!)<s:debug/>访问
4.针对用户每次访问动作类,struts的核心filter都会创建属于自己的vs对象。
////////////////////////////////////
关于ValueStack一些函数用法
void set(String key,Object value):先获取根栈栈顶的Map,如果不存在,压入一个新的Map,把key和value放到这个Map中。如果存在,直接放key和value。
void setValue(String ognlExp ,Object):String是一个OGNL表达式。如果表达式以#开头,操作contextMap。如果不是,设置根栈中对象的某个属性,从顶到尾依次搜寻
Object findValue(String expr):参数是一个OGNL表达式。如果以#开头,从contextMap中找key值所对应的对象。如果不是以#开头,搜索根栈中对象的属性(getter方法)
特别注意:如果编写的表达式不是以#开头,先搜索根栈对象的所有属性,如果没有找到,会把它当做key值到contextMap中找。
String findString(String expr):和findValue功能一样,但把OGNL表达式获取的对象转换成String
OGNL valueStack StackContext(ActionContext)深入分析(转+个人理解)的更多相关文章
- valuestack,stackContext,ActionContext.之间的关系
者之间的关系如下图所示: relation ActionContext 一次Action调用都会创建一个ActionContext 调用:ActionContext context = ActionC ...
- [转] valuestack,stackContext,ActionContext.之间的关系
三者之间的关系如下图所示: ActionContext 一次Action调用都会创建一个ActionContext 调用:ActionContext context = ActionContext ...
- valuestack,stackContext,ActionContext.之间的关系以及如何存取数值的
2013-03-15 10:54 1722人阅读 评论(1) 收藏 举报 分类: J2EE 版权声明:本文为博主原创文章,未经博主允许不得转载. 三者之间的关系如下图所示: ActionCont ...
- valuestack,stackContext,ActionContext.之间的关系以及action的数据在页面中取得的方法
转自:http://blog.csdn.net/quechao123/article/details/4406148 1.三者之间的关系如下图所示: 2.action的数据在页面中取得的方法 在st ...
- struts2中valueStack,stackContext以及actionContext的关系
一,首先给出三者的定义 1.valueStack: 里面存放的是Action类中通过set方法设置的属性值(表单传过来的值等),由OGNL框架实现; 2.stackContext: 也是用来存值的,s ...
- Struts2之ValueStack、ActionContext
今天在看Action获取Resquest.Response时,发现了一个词:值栈.于是今天一天都在看,了解了值栈不仅能知道Action怎么获取request.response等这些,还会了解OGNL语 ...
- 在Struts2中使用ValueStack、ActionContext、ServletContext、request、session等 .
笔者不知道该用哪个词来形容ValueStack.ActionContext等可以在Struts2中用来存放数据的类.这些类使用的范围不同,得到的方法也不同,下面就来一一介绍. 声明:本文参考Strut ...
- java框架之Struts2(3)-OGNL&ValueStack
OGNL 概述 OGNL 是 Object-Graph Navigation Language 的缩写,它是一种第三方的.功能强大的表达式语言,通过它简单一致的表达式语法,可以存取对象的任意属性,调用 ...
- ValueStack、ActionContext
笔者不知道该用哪个词来形容ValueStack.ActionContext等可以在Struts2中用来存放数据的类.这些类使用的范围不同,得到的方法也不同,下面就来一一介绍. 1. ValueStac ...
随机推荐
- 刘汝佳 算法竞赛-入门经典 第二部分 算法篇 第五章 1(String)
第一题:401 - Palindromes UVA : http://uva.onlinejudge.org/index.php?option=com_onlinejudge&Itemid=8 ...
- JS中 判断null
以下是不正确的方法: var exp = null; if (exp == null) { alert("is null"); } exp 为 undefined 时,也会得到与 ...
- 未能正确加载“Microsoft.VisualStudio.Editor.Implementation.EditorPackage”
VS2012启动/加载项目出问题 未能正确加载“Microsoft.VisualStudio.Editor.Implementation.EditorPackage, Microsoft.Visual ...
- hdu 1404/zoj 2725 Digital Deletions 博弈论
暴力打表!! 代码如下: #include<iostream> #include<algorithm> #include<cstdio> #include<c ...
- ip地址+进程端口号+路径参数同样实现restful访问
1.ip地址+进程端口号+路径参数同样实现restful访问 2. 我:还有个问题,龙哥,ip地址+端口+路径参数,也能实现restful访问吧,:可以 我:好我:所以,我只要访问,服务器ip地址+n ...
- RabbitMQ安装与搭建
1.下载Erlang,最新版本是erl8.1 ,地址:http://erlang.org/download/otp_win64_19.1.exe 网上很多资料说安装后要配置环境变量,不过我安装最新的版 ...
- UITableview刷新某一个cell或section
//一个section刷新 NSIndexSet *indexSet=[[NSIndexSet alloc]initWithIndex:2]; [tableview reloadSections:in ...
- android-exploitme(一):生成apk
exploitme是一个国外的android安全测试环境,http://securitycompass.github.io/AndroidLabs/index.html,通过它可以学习一些基本的测试方 ...
- android 使用静态变量传递数据
使用静态变量传递数据之通用方式. 测试应用:当前页面点击button传递数据到一个新的页面显示在textview中. 首先在,mainActivity.xml文件中加入一个button按钮 <B ...
- QQ2013手工去广告
QQ的广告令人讨厌,虽然网上有很多去广告补丁或者是去广告版,但是总是害怕有被盗号的风险,那除了付费会员还有其他什么方法可以安全的去除qq广告吗?显然有,那就是手动去广告. 很简单,不会比使用去广告补丁 ...