struts2 OGNL与标签

一.ActionContext:
ActionContext包含了框架的请求处理过程可以访问的所有数据,包含内容从应用程序数据到会话作用域或者应用程序作用域的映射。所有特定应用程序的数据(例如动作公开的属性),都存储在ValueStack上,它是ActionContext中的一个对象。
所有的OGNL都必须根据ActionContext包含的某一个对象求值。默认情况下,OGNL解析会选择
ValueStack,但如果你愿意,可以指定其他的对象的名字。
一个请求的执行,包含几个重要参数:
1.动作:表示执行的步骤;
2.环境:这个环境指的是包含围绕此动作的执行的所有重要数据和资源的容器;
此处数据指的是:请求的数据,返回的数据,资源数据;
只有这两者比配了才能执行出期望的结果;
ActionContext就是提供了一个动作执行的环境;
包含几个对象:
ValueStack,parameters,application,session,attr,request:
parameters:当前请求中,请求参数的映射;
application:应用程序作用域的属性的映射;
session:会话作用域的属性的映射;
request:请求作用域的属性的映射;
attr:按照页面,请求,会话,应用程序作用域的顺序,查找符合的第一个属性;
valueStack:包含当前请求的应用程序特定领域的所有数据;

二.ValueStack
当struts2接收到一个请求之后,会立即创建一个ActionContext,一个ValueStack和一个动作对象,作为应用程序的数据承载者,动作被马上放到valueStack中,以便框架可以通过OGNL进行访问;
在valueStack上的所有数据有一个共性——特定于应用程序领域;
这是struts2上的一句话:我的理解是特定于当前的请求???
valueStack上没有基础结构的对象,对于一个动作来说,如果动作在valueStack上是因为它是具体数据的承载者,不在此上面是因为它仅仅是动作逻辑;
对于ValueStack来说,可以将他理解为一个摒弃了对象特征的Object,它里面可以存放各种对象,并且将对象的属性进行对外呈现;

三.OGNL
OGNL的上下文是ActionContext,
OGNL与这几个对象的关系,无非是这几个对象作为OGNL求值的rootObject而已,OGNL默认的求值根对象是valueStack,如果需要改变求值的跟对象可以通过:
#session['user']
#mapName['属性名']
当出现以上语句时,框架会在ActionContext中查找session对象,并且进行计算

四.标签
标签中OGNL语法:
%{expression},其实在标签中,struts2,对标签的属性做了很多的默认,有很多标签会对输入的字符串默认为OGNL表达式;
当然我们也可以强制写成%{expression},强制进行OGNL解析;

标签一:<s:property value="**" default="**" escape="**"/>
作用:从ActionContext获取属性值
实例:
<s:property value="#session['test1']"/><br />
从session中获取
<s:property value="user.userName"/><br />
从值栈中获取

如果你个类型没有类型转换器,则必须公开一个toString方法;
对于此标签来说,会将会去的对象转换为字符串输出:
1.调用类型转换方法;
2.没有类型转换调用toString方法;

java代码:
ValueStack vs = invocation.getStack();
vs.set("default", "hello");
ServletActionContext.getContext().getSession().put("test1", "Test1");
ActionContext.getContext().put("ActionContextTest", "ActionContextSuccess");

请注意
ActionContext.getContext().put("ActionContextTest", "ActionContextSuccess");
设置的ActionContextTest属性相当于与ValueStack,request这样的对象并列的地位
相对应的页面获取:
<s:property value="#request['ActionContextTest']"/><br />

放入到ActionContext中却能够从request中获取??
其中的奥妙就在于Struts 2中的org.apache.struts2.dispatcher.StrutsRequestWrapper类,这个类是HttpServletRequest的包装类,它重写了getAttribute()方法(在页面中获取request对象的属性就要调用这个方法),在这个方法中,它首先在请求对象中查找属性,如果没有找到(如果你在ActionContext中保存数据,当然就找不到了),则到ActionContext中去查找。这就是为什么在ActionContext中保存的数据能够从请求对象中得到的原因。

有人想是否可以这样获取呢?
<s:property value="#ActionContextTest"/><br />
当然这样也是没有丝毫问题的,同样可以取到。

标签二:<s:set name="**" scope="**" value="**" />
作用:给一个属性指定一个别名,即可以将此对象的值设置到ActionContext中,也可以设置到任何作用域中;默认为动作作用域内,即ActionContext中;
scope可取值application,session,request,page或者action,默认为action
默认情况下,属性会变为ActionContext的一个命名对象,与valueStack,会话映射齐名。这意味着可以直接使用#myObejct来引用。
举例如下:
<s:set name="userName" value="user.userName" />
<s:property value="#userName"/>
name必须,类型:string  存储的key;
scope否,类型:string   存储的区域;
value必须,类型object   OGNL表达式;

标签三:<s:push value="**">
</s:push>
作用:push标签允许你将属性放在valueStack上,当你将对象放在ValueStack之后,它的所有属性可以通过第一级别的OGNL表达式访问。
当push运行结束后,从valueStack中删除此对象;
<s:push value="user">
  <s:property value="userName"/>
</s:push>
标签四:<s:bean name="**" var="**">
         </s:bean>
作用:与set,push标签的不同是,不需要使用已经存在的对象,自创建一个对象的实例,并且把他放在valuestack上或者设置为ActionContext的顶级作用域;
bean标签像是一个set标签和push标签的混合体,主要的不同是bean标签不使用一个已经存在的对象。你可以新创建一个对象的实例,把它放在ValueStack或者设置为ActionContext的顶级引用。默认情况下,对象会放到valueStack上,并且在标签存在期间一直保存在valueStack上。
如果想在bean之外进行访问,则可以使用var属性为这个对象指定一个引用名,那么这个引用会作为一个命名参数存在于ActionContext中,在请求周期内可以使用#操作符访问这个对象。

标签五:
<s:action name="" namespace="" var="" executeResult="" flush="" ignoreContextParames=""/>
作用:从当前的视图层主动发起动作;

总结:以上是5个标签是数据标签。
property用于从动作作用域即ActionContext中取出数据;
set用于将ActionContext中的某一个深层次的对象设置别名,可以设置到ActionContext中任意对象中,默认是ActionContext中;
push用于将某一对象的访问级别进行提升到ValueStack级别;
bean用于将新创建的对象放入到valueStack或actionContext创建引用;.

猜你喜欢

转载自zhujianguo1981.iteye.com/blog/1721813