struts OGNL学习心得

来源:互联网 发布:webpack seo 编辑:程序博客网 时间:2024/05/17 23:56

 在Struts2里边的OGNL是基于XWork的。XWork的OGNL和普通意义上的OGNL有一些差别,首先最大的差别就是OGNL的顶级对象是一个Context,它提供了一个根对象ValueStack,这是Struts2的OGNL的默认root。所有的action都保存在这个ValueStack中。XWork提供了自己独特的OGNL PropertyAccessor自动从顶向下的查找Stack中符合条件的对象属性。
比如说,有两个对象Animal和Person,两个对象都提供了name属性,同时Animal有species属性,Person有salary属性。假定Animal在stack的顶端。 

 

species 访问animal的属性

salary 访问person属性

name 访问animal的name属性

 

从这里可以看到从顶向下查找的作用。在XWork中,我们可以用[n].name这种方式来访问不同层次的同名属性。n必须是正整数。

[0].name  animal的属性

[1].name  person的属性

 

在Struts2中,采用标准命名的上下文(Context)来处理OGNL表达式。处理OGNL的顶级对象是一个Map(也叫context map),而OGNL在这个context中就是一个顶级对象(root)。在用法上,顶级对象的属性访问,是不需要任何标记前缀的。而其它非顶级的对象访问,需要使用#标记。
Struts2框架把OGNL Context设置为我们的ActionContext。并且ValueStack作为OGNL的根对象。除value stack之外,Struts2框架还把代表application、session、request这些对象的Map对象也放到ActionContext中去。(这也就是Struts2建议在Action类中不要直接访问Servlet API的原因,他可以通过ActionContext对象来部分代替这些功能,以方便对Action类进行测试!)
Action的实例,总是放到value stack中。因为Action放在stack中,而stack是root(根对象),所以对Action中的属性的访问就可以省略#标记。但是,要访问ActionContext中其它对象的属性,就必须要带上#标记,例如:#application.属性  以便让OGNL知道,不是从根对象,而是从其它对象中去寻找。
那么访问Action中的属性的代码就可以这样写

<s:property value="postalCode"/>

其它ActionContext中的非根对象属性的访问要像下面这样写:

<s:property value="#session.mySessionPropKey"/> or<s:property value="#session['mySessionPropKey']"/> or<s:property value="#request['myRequestPropKey']"/>


 使用OGNL

1、“#”主要有三种用途:

 

用于过滤和投影(projecting)集合,如books.{?#this.price<100};
: books.{?#this.price>35} 
构造Map,如#{'foo1':'bar1', 'foo2':'bar2'}。
如: #{'foo1':'bar1', 'foo2':'bar2'}  #{'foo1':'bar1', 'foo2':'bar2'}这种方式常用在给radio或select、checkbox等标签赋值上。如果要在页面中取一个map的值可以这样写: <s:property value="#myMap['foo1']"/>  <s:property value="#myMap['foo1']"/>


 

2、“%”符号的用途是在标签的属性值被理解为字符串类型时,告诉执行环境%{}里的是OGNL表达式。

这是一开始最让我不能理解的符号,原因是一些相关资源在表述时不太准备,经过一翻痛苦的探索,终于明白了它的用途。实际上就是让被理解为字符串的表达式,被真正当成ognl来执行。很有点类似javascript里面的eval()功能,例如 :

 

var Div = eval("document.all.div"+index)

 

var Div = eval("document.all.div"+index)

 

当index变量为1时,语句就会被当作var Div = document.all.div1 var Div = document.all.div1来执行。%{}就是起这个作用。举例:

 

<s:set name="myMap" value="#{'key1':'value1','key2':'value2'}"/>   <s:property value="#myMap['key1']"/>   <s:url value="#myMap['key1']" /></s:set>

 

上面的代码第2行会在页面上输出“value1”,而第3行则会输出"#myMap['key1']"这么一个字符串。 如果将第3行改写成这样:

 

<s:url value="%{#myMap['key1']}"/> 


 

则输出为“value1”。

 

这说明struts2里不同的标签对ognl的表达式的理解是不一样的。如果当有的标签“看不懂”类似“#myMap['key1']”的语句时,就要用%{}来把这括进去,“翻译”一下了。

 

3、“$”有两种用途

 

(1)、在国际化资源文件中,引用OGNL表达式。

 

(2)、在Struts 2配置文件中,引用OGNL表达式:

 

<action name="saveUser" class="userAction" method="save"><result type="redirect">listUser.action?msg=${msg}</result></action>


原创粉丝点击