struts2的ognl与valuestack

来源:互联网 发布:javascript 书 编辑:程序博客网 时间:2024/04/30 21:59

1.Ognl

ognl就一种,导航式的表达式语言,就是按照层次结构来表达。
其中Ognl可以有一个Context就是一个map对象。
这里涉及一个根的问题,默认没有添加到Context的就是根对象。
查找一个表达式的时候,从根开始,然后逐层向下查找。不是根的对象访问 需要加#号。

是根对象的话,直接访问。


2.struts2是这样做的。

struts2中ActionContext相当于 Ognl中 context上下文。

ActionContext会存放很多变量,如下所示:



其中 valuestack是 根,也就是说 可以直接方法值栈中的内容,而访问 其他的 如session的内容就要使用#号。

其中值栈中存放的是 action 还有一个DefaultTextProvider 。默认好像是 两个。

Struts2总是把当前Action实例放置在栈顶。所以在OGNL中引用Action中的属性也可以省略“#”。

因此我们就可以访问 acion的属性了。



我们可以通过,
ActionContext actionContext =ActionContext.getContext();
ValueStack stack=actionContext .getValueStack();
来获取当前访问的action的ActionContext。
然后获取其值栈,大多数时候值栈中只有两个东西
my1.HelloWorldAction@1995d80
com.opensymphony.xwork2.DefaultTextProvider@1c9b9ca

一个是当前的action实例,另一个是DefaultTextProvider实例。
我们知道 actionAcontext其实就是 Ognl中的map。只是把Ognl中的map重组包装一下。
这里可以通过actionContext .getContextMap()获取这个map,当然也可以通过stack.getContext()获取,这个获取的结果用“==”显示是true的。



需要注意的一点是:

当访问一个action的时候,此时struts2会把整个action压入valuestack的顶部,此时valuestack就一个action对象。

我们通常会写stack.set(key1,value1)或者statck.setvalue(key2,value2)这两个是有区别的,前者 会在valuestack压入一个hashmap,并将key1,value1植入该hashmap那么此时valuestack会有两个对象,顶部是 hashmap,底部是action

后者会将key2,value2直接植入到顶部的对象,通常是action,假如action没有相应的set方法, 那么执行这个方法等于白搭,你假如此时执行valuestack.findvalue就会为空,顶部如果是已有的map,那么直接进入map,总之 就是直接植入到栈顶


  我们知道,OGNL上下文中的根对象可以直接访问,不需要使用任何特殊的“标记”,而引用上下文中的其他对象则需要使用“#”来标记。由于值栈是上下文中的根对象,因此可以直接访问。那么对于值栈中的对象该如何访问呢?Struts2提供了一个特殊的OGNLPropertyAccessor,它可以自动查找栈内的所有对象(从栈顶到栈底),直接找到一个具有你所查找的属性的对象。也就是说,对于值栈中的任何对象都可以直接访问,而不需要使用“#”。

其他资料

  5、值栈中的Action实例
    
Struts2框架总是把Action实例放在栈顶。因为Action在值栈中,而值栈又是OGNL中的根,所以引用Action的属性可以省略“#”标记,这也是为什么我们在结果页面中可以直接访问Action的属性的原因。
  6、Struts2中的命名对象
    Struts2还提供了一些命名对象,这些对象没有保存在值栈中,而是保存在ActionContext中,因此访问这些对象需要使用“#”标记。这些命名对象都是Map类型。
   parameters
    用于访问请求参数。如:#parameters['id']或#parameters.id,相当于调用了HttpServletRequest对象的getParameter()方法。
    注意,parameters本质上是一个使用HttpServletRequest对象中的请求参数构造的Map对象,一量对象被创建(在调用Action实例之前就已经创建好了),它和HttpServletRequest对象就没有了任何关系。
   request
    用于访问请求属性。如:#request['user']或#request.user,相当于调用了HttpServletRequest对象的getAttribute()方法。
   session
    用于访问session属性。如:#session['user']或#session.user,相当于调用了HttpSession对象的getAttribute()方法。
   application
    用于访问application属性。如:#application['user']或#application.user,相当于调用了ServletContext的getAttribute()方法。
   attr
    如果PageContext可用,则访问PageContext,否则依次搜索request、session和application对象。





OGNL中重要的3个符号:#、%、$:

#、%和$符号在OGNL表达式中经常出现,而这三种符号也是开发者不容易掌握和理解的部分,需要时间的积累才渐渐弄清楚……

1.#符号

#符号的用途一般有三种。

—    访问非根对象属性,例如#session.msg表达式,由于Struts 2中值栈被视为根对象,所以访问其他非根对象时,需要加#前缀。实际上,#相当于ActionContext. getContext();#session.msg表达式相当于ActionContext.getContext().getSession(). getAttribute("msg") 。

—    用于过滤和投影(projecting)集合,如persons.{?#this.age>25},persons.{?#this.name=='pla1'}.{age}[0]。

—    用来构造Map,例如示例中的#{'foo1':'bar1', 'foo2':'bar2'}。

2.%符号

%符号的用途是在标志的属性为字符串类型时,计算OGNL表达式的值,这个类似js中的eval,很暴力。

3.$符号

$符号主要有两个方面的用途。

—    在国际化资源文件中,引用OGNL表达式,例如国际化资源文件中的代码:reg.agerange=国际化资源信息:年龄必须在${min}同${max}之间。

—    在Struts 2框架的配置文件中引用OGNL表达式,例如:

<validators>        <field name="intb">                <field-validator type="int">                <param name="min">10</param>                <param name="max">100</param>                <message>BAction-test校验:数字必须为${min}为${max}之间!</message>            </field-validator>        </field>    </validators> 



ognl静态方法调用


使用ognl,可以在页面标签中直接调用java类中的方法

示例:
调用:cn.hl.zone.util包下,StringUtil类中的getDescString方法
operParams:参数

<s:property value="@cn.hl.zone.util.StringUtil@getDescString(operParams)"/>

0 0
原创粉丝点击