Struts2 OGNL与标签使用

来源:互联网 发布:mysql分表 语法 编辑:程序博客网 时间:2024/04/26 17:14

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
Mapsize
isEmptyList.size()        List.isEmpty()
Set.size()        Set.isEmpty()
Map.size()       Map.isEmpty()List
SetiteratorList.iterator()
Set.iterator()Mapkeys
valuesMap.keySet()
Map.values()Iteratornext
hasNextIterator.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 + 1IteratorStatusevenindex + 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 表达式,否则,标签属性的值会被当做是一个普通的字符串来处理。

0 0
原创粉丝点击