现在的位置: 首页 > 综合 > 正文

Struts2中的OGNL详解

2013年10月15日 ⁄ 综合 ⁄ 共 11119字 ⁄ 字号 评论关闭

首先了解下OGNL的概念

OGNL是Object-Graph Navigation Language的缩写,全称为对象图导航语言,是一种功能强大的表达式语言,它通过简单一致的语法,可以任意存取对象的属性或者调用对象的方法,能够遍历整个对象的结构图,实现对象属性类型的转换等功能。

此外,还得先需弄懂OGNL的一些知识:

1.OGNL表达式的计算是围绕OGNL上下文进行的。
OGNL上下文实际上就是一个Map对象,由ognl.OgnlContext类表示。它里面可以存放很多个JavaBean对象。它有一个上下文根对象。
上下文中的根对象可以直接使用名来访问或直接使用它的属性名访问它的属性值。否则要加前缀“#key”。

2.Struts2的标签库都是使用OGNL表达式来访问ActionContext中的对象数据的。如:<s:propertyvalue="xxx"/>。

3.Struts2将ActionContext设置为OGNL上下文,并将值栈作为OGNL的根对象放置到ActionContext中。

4.值栈(ValueStack) :
可以在值栈中放入、删除、查询对象。访问值栈中的对象不用“#”。
Struts2总是把当前Action实例放置在栈顶。所以在OGNL中引用Action中的属性也可以省略“#”。
5.调用ActionContext的put(key,value)放入的数据,需要使用#访问。

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表达式,例如:

  1. <validators>   
  2.     <field
    name="intb">   
  3.             <field-validator
    type="int">   
  4.             <param
    name="min">10</param>   
  5.             <param
    name="max">100</param>   
  6.             <message>BAction-test校验:数字必须为${min}为${max}之间!</message>   
  7.         </field-validator>   
  8.     </field>   
  9. </validators>  

下面通过代码对OGNL有更深的了解:

action类OgnlAction.java:
  1. package com.tjcyjd.test.action; 
  2.  
  3. import java.util.Date; 
  4. import java.util.LinkedList; 
  5. import java.util.List; 
  6.  
  7. import javax.servlet.http.HttpServletRequest; 
  8.  
  9. import org.apache.struts2.ServletActionContext; 
  10. import org.apache.struts2.convention.annotation.Action; 
  11. import org.apache.struts2.convention.annotation.Namespace; 
  12. import org.apache.struts2.convention.annotation.ParentPackage; 
  13. import org.apache.struts2.convention.annotation.Result; 
  14. import org.apache.struts2.convention.annotation.Results; 
  15. import org.springframework.stereotype.Controller; 
  16.  
  17. import com.opensymphony.xwork2.ActionContext; 
  18. import com.opensymphony.xwork2.ActionSupport; 
  19.  
  20. @Controller 
  21. @Namespace("/test"
  22. @ParentPackage("struts-default"
  23. @Results( { @Result(name =
    "success", location = "/other_test/showognl.jsp"), 
  24.         @Result(name = "fail", location =
    "/bbs/admin_login.jsp"), 
  25.         @Result(name =
    "input", location = "/bbs/admin_login.jsp") }) 
  26. public class OgnlAction
    extends ActionSupport { 
  27.     private static
    final long serialVersionUID = -1494290883433357310L; 
  28.     private List<Person> persons; 
  29.  
  30.     @Action("ognlTest"
  31.     public String ognlTest()
    throws Exception { 
  32.         // 获得ActionContext实例,以便访问Servlet API 
  33.         ActionContext ctx = ActionContext.getContext(); 
  34.         // 存入application 
  35.         ctx.getApplication().put("msg",
    "application信息"); 
  36.         // 保存session 
  37.         ctx.getSession().put("msg",
    "seesion信息"); 
  38.         // 保存request信息 
  39.         HttpServletRequest request = ServletActionContext.getRequest(); 
  40.         request.setAttribute("msg",
    "request信息"); 
  41.         // 为persons赋值 
  42.         persons = new LinkedList<Person>(); 
  43.         Person person1 = new Person(); 
  44.         person1.setName("pla1"); 
  45.         person1.setAge(26); 
  46.         person1.setBirthday(new Date()); 
  47.         persons.add(person1); 
  48.  
  49.         Person person2 = new Person(); 
  50.         person2.setName("pla2"); 
  51.         person2.setAge(36); 
  52.         person2.setBirthday(new Date()); 
  53.         persons.add(person2); 
  54.  
  55.         Person person3 = new Person(); 
  56.         person3.setName("pla3"); 
  57.         person3.setAge(16); 
  58.         person3.setBirthday(new Date()); 
  59.         persons.add(person3); 
  60.  
  61.         return SUCCESS; 
  62.  
  63.     } 
  64.  
  65.     public List<Person> getPersons() { 
  66.         return persons; 
  67.     } 
  68.  
  69.     public void setPersons(List<Person> persons) { 
  70.         this.persons = persons; 
  71.     } 

jsp页面showognl.jsp:

  1. <%@ page language="java"
    contentType="text/html; charset=utf-8"
    pageEncoding="utf-8" %>   
  2.    
  3. <%@ taglib prefix="s"
    uri="/struts-tags" %>   
  4. <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/ xhtml1/DTD/xhtml1-transitional.dtd">   
  5.    
  6. <html
    xmlns="http://www.w3.org/1999/xhtml">   
  7.    
  8. <head>   
  9.    
  10.     <title>Struts2 OGNL 演示</title>   
  11.    
  12. </head>   
  13.    
  14. <body>       
  15.    
  16.     <h3>访问OGNL上下文和Action上下文</h3>   
  17.    
  18.     <!-使用OGNL访问属性值-->   
  19.    
  20.     <p>parameters:
    <s:property
    value="#parameters.msg"
    /></p>   
  21.    
  22.     <p>request.msg:
    <s:property
    value="#request.msg"
    /></p>   
  23.    
  24.     <p>session.msg:
    <s:property
    value="#session.msg"
    /></p>   
  25.    
  26.     <p>application.msg:
    <s:property
    value="#application.msg"
    /></p>   
  27.    
  28.     <p>attr.msg:
    <s:property
    value="#attr.msg"
    /></p>   
  29.    
  30.     <hr
    />   
  31.    
  32.     <h3>用于过滤和投影(projecting)集合</h3>   
  33.    
  34.     <p>年龄大于20</p>   
  35.    
  36.     <ul>   
  37.    
  38.     <!-判断年龄-->   
  39.    
  40.         <s:iterator
    value="persons.{?#this.age>20}">   
  41.    
  42.             <li><s:property
    value="name"
    /> - 年龄:<s:property
    value="age"
    /></li>   
  43.    
  44.         </s:iterator>   
  45.    
  46.     </ul>   
  47.    
  48.     <p>姓名为pla1的年龄:
    <s:property
    value="persons.{?#this.name=='pla1'}.{age}[0]"/></p>   
  49.    
  50.     <hr
    />   
  51.    
  52.     <h3>构造Map</h3>   
  53.    
  54.     <s:set
    name="foobar"
    value="#{'foo1':'bar1', 'foo2':'bar2'}"
    />   
  55.    
  56.     <p>The value of key "foo1" is
    <s:property
    value="#foobar['foo1']"
    /></p>   
  57.      
  58.     <hr
    />  
  59.      
  60.     <h4>%符号的用法</h4>   
  61.    
  62.     <s:set
    name="foobar"
    value="#{'foo1':'bar1', 'foo2':'bar2'}"
    />   
  63.    
  64.     <p>The value of key "foo1" is
    <s:property
    value="#foobar['foo1']"
    /></p>   
  65.    
  66.     <p>不使用%:<s:url
    value="#foobar['foo1']"
    /></p>   
  67.    
  68.     <p>使用%:<s:url
    value="%{#foobar['foo1']}"
    /></p>   
  69.    
  70.     <hr
    /> 
  71.         <%   
  72.             request.setAttribute("req", "request scope");   
  73.             request.getSession().setAttribute("sess", "session scope");   
  74.             request.getSession().getServletContext().setAttribute("app",   
  75.                     "aplication scope");   
  76.         %>   
  77.         1.通过ognl表达式获取 属性范围中的值   
  78.         <br>   
  79.         <s:property
    value="#request.req"
    />   
  80.         <br
    />   
  81.         <s:property
    value="#session.sess"
    />   
  82.         <br
    />   
  83.         <s:property
    value="#application.app"
    />   
  84.         <br
    />   
  85.         <hr>   
  86.    
  87.        2.通过<span
    style="background-color: #fafafa;">ognl表达式创建list 集合 ,并且遍历出集合中的值   
  88.         <br>   
  89.         <s:set
    name="list"
    value="{'eeeee','ddddd','ccccc','bbbbb','aaaaa'}"></s:set>   
  90.         <s:iterator
    value="#list"
    var="o">   
  91.             <!-- ${o }<br/> -->   
  92.             <s:property
    />   
  93.             <br
    />   
  94.         </s:iterator>   
  95.         <br
    />   
  96.         <hr>   
  97.    
  98.        3.通过ognl表达式创建Map 集合 ,并且遍历出集合中的值   
  99.         <br>   
  100.         <s:set
    name="map"   
  101.             value="#{'1':'eeeee','2':'ddddd','3':'ccccc','4':'bbbbb','5':'aaaaa'}"></s:set>   
  102.         <s:iterator
    value="#map"
    var="o">   
  103.             <!--      ${o.key }->${o.value }<br/>   -->   
  104.             <!-- <s:property value="#o.key"/>-><s:property value="#o.value"/><br/>   -->   
  105.             <s:property
    value="key"
    />-><s:property
    value="value"
    />   
  106.             <br
    />   
  107.         </s:iterator>   
  108.         <br
    />   
  109.         <hr>   
  110.       4.通过ognl表达式 进行逻辑判断   
  111.         <br>   
  112.         <s:if
    test="'aa' in {'aaa','bbb'}">   
  113.             aa 在 集合{'aaa','bbb'}中;   
  114.         </s:if>   
  115.         <s:else>   
  116.             aa 不在 集合{'aaa','bbb'}中;   
  117.         </s:else>   
  118.         <br
    />   
  119.         <s:if
    test="#request.req not in #list">   
  120.                 不 在 集合list中;   
  121.         </s:if>   
  122.         <s:else>   
  123.              在 集合list中;   
  124.         </s:else>   
  125.         <br
    />   
  126.         <hr>   
  127.          
  128.        5.通过ognl表达式 的投影功能进行数据筛选   
  129.         <br>   
  130.         <s:set
    name="list1"
    value="{1,2,3,4,5}"></s:set>   
  131.         <s:iterator
    value="#list1.{?#this>2}"
    var="o">   
  132.             <!-- #list.{?#this>2}:在list1集合迭代的时候,从中筛选出当前迭代对象>2的集合进行显示 -->   
  133.             ${o }<br
    />   
  134.         </s:iterator>   
  135.         <br
    />   
  136.         <hr>   
  137.        6.通过ognl表达式 访问某个类的静态方法和值   
  138.         <br>   
  139.         <s:property
    value="@java.lang.Math@floor(32.56)"
    />   
  140.    
  141.         <s:property
    value="@com.rao.struts2.action.OGNL1Action@aa"
    />   
  142.         <br
    />   
  143.         <br
    />   
  144.         <hr>   
  145.       7.ognl表达式 迭代标签 详细   
  146.         <br>   
  147.         <s:set
    name="list2"   
  148.             value="{'aa','bb','cc','dd','ee','ff','gg','hh','ii','jj'}"></s:set>   
  149.         <table
    border="1">   
  150.             <tr>   
  151.                 <td>索引
    </td>   
  152.                 <td></td>   
  153.                 <td>奇?</td>   
  154.                 <td> 偶?</td>   
  155.                 <td>首?</td>   
  156.                 <td> 尾?</td>   
  157.                 <td>当前迭代数量</td>   
  158.             </tr>   
  159.             <s:iterator
    value="#list2"
    var="o"
    status="s">   
  160.                 <tr
    bgcolor="<s:if test="#s.even">pink</s:if>">   
  161.                     <td>   
  162.                         <s:property
    value="#s.getIndex()"
    />   
  163.                     </td>   
  164.                     <td>   
  165.                         <s:property
    />   
  166.                     </td>   
  167.                     <td>   
  168.                         <s:if
    test="#s.odd">Y</s:if>   
  169.                         <s:else>N</s:else>   
  170.                     </td>   
  171.                     <td>   
  172.                         <s:if
    test="#s.even">Y</s:if>   
  173.                         <s:else>N</s:else>   
  174.                     </td>   
  175.                     <td>   
  176.                         <s:if
    test="#s.first">Y</s:if>   
  177.                         <s:else>N</s:else>   
  178.                     </td>   
  179.                     <td>   
  180.                         <s:if
    test="#s.isLast()">Y</s:if>   
  181.                         <s:else>N</s:else>   
  182.                     </td>   
  183.                     <td>   
  184.                     <s:property
    value="#s.getCount()"/>   
  185.                 </td>   
  186.                 </tr>   
  187.             </s:iterator>   
  188.         </table>   
  189.         <br>   
  190.         <hr>        
  191.          
  192.          
  193.        8.ognl表达式:  if/else if/else 详细<br>   
  194.         <% request.setAttribute("aa",0); %>   
  195.         <s:if
    test="#request.aa>=0 && #request.aa<=4">   
  196.                 在0-4之间;   
  197.         </s:if>   
  198.         <s:elseif
    test="#request.aa>=4 && #request.aa<=8">   
  199.                 在4-8之间;   
  200.         </s:elseif>   
  201.         <s:else>   
  202.              大于8;   
  203.         </s:else>   
  204.         <br>   
  205.         <hr>   
  206.     9.ognl表达式: url 详细<br>   
  207.         <% request.setAttribute("aa","sss"); %>   
  208.         <s:url
    action="testAction"
    namespace="/aa/bb">   
  209.             <s:param
    name="aa"
    value="#request.aa"></s:param>   
  210.             <s:param
    name="id">100</s:param>   
  211.         </s:url>   
  212.         <br/>   
  213.         <s:set
    name="myurl"
    value="'http://www.baidu.com'"></s:set>   
  214.         value以字符处理:   <s:url
    value="#myurl"></s:url><br>   
  215.         value明确指定以ognl表达式处理:    <s:url
    value="%{#myurl}"></s:url>   
  216.         <br>   
  217.         <hr>   
  218.     10.ognl表达式: checkboxlist 详细<br>   
  219.         1> .list 生成;~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~<br>   
  220.         name:checkboxlist的名字<br>   
  221.         list:checkboxlist要显示的列表<br>   
  222.         value:checkboxlist默认被选中的选项,checkedchecked=checked<br>   
  223.         <s:checkboxlist
    name="checkbox1"
    list="{'上网','看书','爬山','游泳','唱歌'}"
    value="{'上网','看书'}"
    ></s:checkboxlist>   
  224.         <br>   
  225.          以上生成代码:<br>   
  226.         <xmp>   
  227.             <input
    type="checkbox"
    name="checkbox1"
    value="上网"
    id="checkbox1-1"
    checked="checked"/>   
  228.             <label
    for="checkbox1-1"
    class="checkboxLabel">上网</label>   
  229.             <input
    type="checkbox"
    name="checkbox1"
    value="看书"
    id="checkbox1-2"
    checked="checked"/>   
  230.             <label
    for="checkbox1-2"
    class="checkboxLabel">看书</label>   
  231.             <input
    type="checkbox"
    name="checkbox1"
    value="爬山"
    id="checkbox1-3"/>   
  232.             <label
    for="checkbox1-3"
    class="checkboxLabel">爬山</label>   
  233.             <input
    type="checkbox"
    name="checkbox1"
    value="游泳"
    id="checkbox1-4"/>   
  234.             <label
    for="checkbox1-4"
    class="checkboxLabel">游泳</label>   
  235.             <input
    type="checkbox"
    name=

抱歉!评论已关闭.