Struts2中的OGNL详解 《转》

Posted 夏冬青

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Struts2中的OGNL详解 《转》相关的知识,希望对你有一定的参考价值。

首先了解下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.     }  
  72. }  

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="#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="@[email protected](32.56)" />    
  140.     
  141.         <s:property value="@[email protected]/>    
  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.        &n

    以上是关于Struts2中的OGNL详解 《转》的主要内容,如果未能解决你的问题,请参考以下文章

    Struts2 OGNL

    第四节 Struts2 - OGNL详解

    基于初学者的SSHstruts2 值栈的详解与struts2标签库+ognl表达式

    关于Struts2中的ognl-2.6.11.jar和ognl-2.7.3.jar解决思路

    (补充)9.Struts2中的OGNL表达式

    Struts2(Ognl)