Struts2 OGNL与标签使用

OGNL:

OGNL ( Object Graph Navigation Language ),对象图导航语言。这是一种强大的表达式语言,通过它可以非常方便的来操作对象属性。 
在 Struts2 中,OGNL 需要和 Struts2 标签库配套来使用。

OGNL context

                               | 
                               | -- application 
                               | 
                               | -- session 
                               | 
                               | -- value  stack ( root ) 
context  map  ---- | 
                               | -- request 
                               | 
                               | -- parameters 
                               | 
                               | -- attr ( searches page, request, session, then application scopes ) 
                               | 
Struts2 框架将 OGNL context 设置为我们的 ActionContext,并将 ValueStack 作为 OGNL 的根对象。而 Action 则置于 ValueStack 的最顶层。 
除此之外,Struts2 框架还把代表 application、request、session 对象的 Map 对象也放到 ActionContext 中,使得 Action 与 Servlet API 解耦。

名称描述
ValueStack值栈,作为 OGNL 上下文的根对象。通过 KEY 来访问,非根对象需要用 #KEY 来访问
parametersMap 类型,封装了请求中的所有参数。访问 #parameters.name 相当于调用 HttpServletRequest.getParameter( )
requestMap 类型,封装了 request 对象中的所有属性。访问 #request.name 相当于调用 HttpServletRequest.getAttribute( )
sessionMap 类型,封装了 session 对象中的所有属性。访问 #session.name 相当于调用 HttpSession.getAttribute( )
applicationMap 类型,封装了 application 对象中的所有属性。访问 #application.name 相当于调用 ServletContext.getAttribute( )
attrMap 类型,依次从 page、request、session、application 对象中检索属性的值

OGNL 访问 Action 中的数据

Action 位于值栈的栈顶位置,而值栈又是 OGNL 的根对象,因此,在 OGNL 表达式中可直接使用属性名称来访问 Action 当中的数据。如:  
<s:property value="name" />  
实际上,这里是通过调用 Action 当中的 getName( ) 方法来获取得到数据的,而不管 Action 当中是否有一个名称为 name 的属性变量。  
因此,如果需要在页面中获取得到 Action 当中的数据,你只需要为你的 Action 类编写 getXX( ) 方法就可以了。

OGNL 访问对象属性

<  s:property   value  ="subject"  /> 
<  s:property   value  ="person.name"  /> 
<  s:property   value  ="person.idcard.number"  />

OGNL 调用方法

<  s:property   value  ="person.getName()"  /> 
<  s:property   value  ="person.name.toUpperCase()"  />

OGNL 调用静态属性

<  s:property   value  ="@fan.tutorial.model.Person@VERSION"  />

OGNL 调用静态方法

<!--   在 struts.xml 中添加下面这行配置   --> 
<!--   <constant name="struts.ognl.allowStaticMethodAccess" value="true"/>   --> 
<  s:property   value  ="@fan.tutorial.model.Person@getVersion()"  />

OGNL 调用构造方法

<  s:property   value  ="new fan.tutorial.model.Address('广东茂名').name"  />

OGNL 使用索引访问数组和列表

<  s:property   value  ="array[0]"  /> 
<  s:property   value  ="personList[0].name"  />

OGNL 操作符运算

<  s:property   value  ="array[0] + 1"  /> 
<  s:property   value  ="array[0] - 1"  /> 
<  s:property   value  ="array[0] * 2"  /> 
<  s:property   value  ="array[0] / 2"  /> 
<  s:property   value  ="array[0] % 3"  />

OGNL 逻辑运算符

<  s:set   name  ="x"   value  ="5"  /> 
<  s:property   value  ="#x in array"  /> 
<  s:property   value  ="#x not in array"  /> 
<  s:property   value  ="#x > array[0]"  /> 
<  s:property   value  ="#x >= array[0]"  /> 
<  s:property   value  ="#x < array[0]"  /> 
<  s:property   value  ="#x <= array[0]"  /> 
<  s:property   value  ="#x == array[0]"  /> 
<  s:property   value  ="#x != array[0]"  />

OGNL 访问命名对象 ( parameters、request、session、application、attr )

<  s:property   value  ="#parameters.author"  /> 
<  s:property   value  ="#request.message"  /> 
<  s:property   value  ="#session.message"  /> 
<  s:property   value  ="#application.message"  /> 
<  s:property   value  ="#attr.message"  />

OGNL 访问集合的伪属性

类型伪属性伪属性对应的 Java 方法
List
Set
Map
size
isEmpty
List.size()        List.isEmpty()
Set.size()        Set.isEmpty()
Map.size()       Map.isEmpty()
List
Set
iteratorList.iterator()
Set.iterator()
Mapkeys
values
Map.keySet()
Map.values()
Iteratornext
hasNext
Iterator.next()
Iterator.hasNext()

<  s:property   value  ="personList.size"  /> 
<  s:property   value  ="personList.isEmpty"  /> 
<  s:property   value  ="map.keys"  /> 
<  s:property   value  ="map.values"  /> 
<  s:property   value  ="personList.iterator.hasNext"  /> 
<  s:property   value  ="personList.iterator.next.name"  /> 
<  s:property   value  ="person.addressSet.iterator.hasNext"  /> 
<  s:property   value  ="person.addressSet.iterator.next.name"  />

OGNL 迭代集合

类型伪属性伪属性的作用描述
IteratorStatusindex当前元素的索引
IteratorStatusfirst当前元素是否是集合的第一个元素
IteratorStatuslast当前元素是否是集合的最后一个元素
IteratorStatuscount当前迭代元素的数量,count = index + 1
IteratorStatusevenindex + 1 是否为偶数
IteratorStatusoddindex + 1 是否为奇数

<  table  > 
    <  tr   align  ="center"  > 
      <  td   width  ="2%"  >索引  </  td  > 
      <  td   width  ="5%"  >值  </  td  > 
      <  td   width  ="8%"  >当前迭代的数量  </  td  > 
      <  td   width  ="8%"  >迭代奇偶性  </  td  > 
      <  td   width  ="8%"  >集合第一个元素  </  td  > 
      <  td   width  ="8%"  >集合最后一个元素  </  td  > 
    </  tr  > 
    <  s:iterator   value  ="array"   var  ="a"   status  ="status"  > 
      <  tr   align  ="center"  > 
        <  td  > 
          <  s:property   value  ="#status.index"  /> 
        </  td  > 
        <  td  > 
          <  s:property  /> 
        </  td  > 
        <  td  > 
          <  s:property   value  ="#status.count"  /> 
        </  td  > 
        <  td  > 
          <  s:if   test  ="#status.even"  >偶  </  s:if  > 
          <  s:if   test  ="#status.odd"  >奇  </  s:if  > 
        </  td  > 
        <  td  > 
          <  s:if   test  ="#status.first"  >是  </  s:if  > 
          <  s:else  >否  </  s:else  > 
        </  td  > 
        <  td  > 
          <  s:if   test  ="#status.last"  >是  </  s:if  > 
          <  s:else  >否  </  s:else  > 
        </  td  > 
      </  tr  > 
    </  s:iterator  > 
</  table  >

OGNL 投影

如果把集合中的数据想象成是数据库表中的数据,那么,投影就是从这张表中选取某一列所构成的一个新的集合。投影的语法:
collection.{expression}
<  s:property   value  ="personList.{name}"  />

OGNL 过滤

OGNL 过滤也称为选择,就是把满足 OGNL 表达式的结果选择出来构成一个新的集合。  
过滤的语法:collection.{?expression} 或 collection.{^expression} 或 collection.{$expression}
符号作用
?选取与逻辑表达式匹配的所有结果
^选取与逻辑表达式匹配的第一个结果
$选择与逻辑表达式匹配的最后一个结果
#this代表当前迭代的元素

<  s:property   value  ="array.{?#this > 5}"  /> 
<  s:property   value  ="array.{^#this > 5}"  /> 
<  s:property   value  ="array.{$#this > 5}"  />


投影和过滤

<  s:property   value  ="personList.{?#this.sex.equals('female')}.{name}"  /> 
<  s:property   value  ="personList.{^#this.sex.equals('female')}.{name}"  /> 
<  s:property   value  ="personList.{$#this.sex.equals('female')}.{name}"  />

OGNL %{ } 语法

对于 ${ } 也许你并不会陌生,${ } 是 EL 表达式的语法,这里的 %{ } 是 OGNL 表达式的语法。  
也许你开始困惑,上面示例不是都在使用 OGNL 表达式吗?!没见 %{ } 出现过啊!好眼力!凡是属于 OGNL 表达式的串,你都可以使用 %{ } 来将它们包裹住,但这不是必须的。例如 <s:property value="expression" /> 中的 expression 在任何时候都是被当做 OGNL 表达式来处理的。

<  s:property   value  ="subject"  />    <!--   subject被OGNL进行表达式求值输出   --> 
<  s:property   value  ="i love java so much"  />    <!--   什么都不输出   -->

第2行之所以什么都不输出,是因为执行时环境把 i love java so much 这个字符串也当做是一个 OGNL 表达式来处理了,但在 OGNL 上下文中并找不到与这个 KEY 对应的值,因此什么都没有输出。  
这是由于 <s:property /> 标签的 value 属性是 Object 类型引起的,凡是 Object 类型的标签属性的值,都会被当做是一个 OGNL 表达式来处理。  
这种情况下的解决办法是:使用单引号将它们引起来,表明这是一个普通的字符串,而不是 OGNL 表达式。

<  s:property   value  ="'subject'"  />    <!--   输出 subject   --> 
<  s:property   value  ="'i love java so much'"  />    <!--   输出 i love java so much   -->

再如 <s:textfield value="expression" /> 中的 expression 什么时候被当做 OGNL 表达式来处理就要取决于你是否使用了 %{ } 语法,如果使用了,那么它就是一个 OGNL 表达式,如果没有使用,那么它就只是一个普通的字符串而已。

<  s:textfield   value  ="author"  />           <!--   author被当做普通字符串原样输出   --> 
<  s:textfield   value  ="%{author}"  />        <!--   author被OGNL进行表达式求值输出   --> 
<  s:textfield   value  ="person.name"  />      <!--   person.name被当做普通字符串原样输出   --> 
<  s:textfield   value  ="%{person.name}"  />   <!--   person.name被OGNL进行表达式求值输出   -->

这是由于 <s:textfield /> 标签的 value 属性是 String 类型引起的,凡是非 Object 类型的标签属性的值,是不会被当做一个 OGNL 表达式来处理的,  
除非你使用了 %{ expression } 语法,执行时环境才会将 expression 当做是一个 OGNL 表达式来处理。  
只有当你理解了上面的2个案例,你才能正确的使用 OGNL 表达式。  
实际上规则非常简单,当标签属性的类型为 Object 类型时,标签属性的值就会被当做是一个 OGNL 表达式来处理,因此可省略 %{} ;  
当标签属性的类型为 String 类型时,除非你使用了 %{ } 语法告诉执行时环境这是一个 OGNL 表达式,否则,标签属性的值会被当做是一个普通的字符串来处理。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值