首页 诗词 字典 板报 句子 名言 友答 励志 学校 网站地图
当前位置: 首页 > 教程频道 > 软件管理 > 软件架构设计 >

ognl概念跟原理详解

2012-11-15 
ognl概念和原理详解针对上面的话,我们可以简单的理解为下面两点:A) 针对根对象(Root Object)的操作,表达式

ognl概念和原理详解

针对上面的话,我们可以简单的理解为下面两点:

A) 针对根对象(Root Object)的操作,表达式是自根对象到被访问对象的某个链式操作的字符串表示。

B) 针对上下文环境(Context)的操作,表达式是自上下文环境(Context)到被访问对象的某个链式操作的字符串表示,但是必须在这个字符串的前面加上#符号,以表示与访问根对象的区别。

OGNL三要素:

???? 很多人习惯上把传入OGNL的API的三个参数,称之为OGNL的三要素。OGNL的操作实际上就是围绕着这三个参数而进行的。

看下面一段测试代码:


????? 当Struts2接受一个请求时,会迅速创建ActionContext,ValueStack,action 。然后把action存放进ValueStack,所以action的实例变量可以被OGNL访问。访问上下文(Context)中的对象需要使用#符号标注命名空间,如#application、#session,另外OGNL会设定一个根对象(root对象),在Struts2中根对象就是ValueStack(值栈) 。如果要访问根对象(即ValueStack)中对象的属性,则可以省略#命名空间,直接访问该对象的属性即可。

?????? 在struts2中,根对象ValueStack的实现类为OgnlValueStack,该对象不是我们想像的只存放单个值,而是存放一组对象。在OgnlValueStack类里有一个List类型的root变量,就是使用他存放一组对象 |--request |--application context ------|--OgnlValueStack root变量[action, OgnlUtil, ... ] |--session |--attr |--parameters,在root变量中处于第一位的对象叫栈顶对象。通常我们在OGNL表达式里直接写上属性的名称即可访问root变量里对象的属性,搜索顺序是从栈顶对象开始寻找,如果栈顶对象不存在该属性,就会从第二个对象寻找,如果没有找到就从第三个对象寻找,依次往下访问,直到找到为止。 大家注意: Struts2中,OGNL表达式需要配合Struts标签才可以使用。如:<s:property value="name"/>

?????? 由于ValueStack(值栈)是Struts 2中OGNL的根对象,如果用户需要访问值栈中的对象,在JSP页面可以直接通过下面的EL表达式访问ValueStack(值栈)中对象的属性: ${foo} //获得值栈中某个对象的foo属性。如果访问其他Context中的对象,由于他们不是根对象,所以在访问时,需要添加#前缀。

application对象:用于访问ServletContext,例如#application.userName或者#application['userName'],相当于调用ServletContext的getAttribute("username")。
session对象:用来访问HttpSession,例如#session.userName或者#session['userName'],相当于调用session.getAttribute("userName")。
request对象:用来访问HttpServletRequest属性(attribute)的Map,例如#request.userName或者#request['userName'],相当于调用request.getAttribute("userName")。

parameters对象:用于访问HTTP的请求参数,例如#parameters.userName或者#parameters['userName'],相当于调用request.getParameter("username")。
attr对象:用于按page->request->session->application顺序访问其属性。

??????????? 好了,基本概念和原理占时先介绍到这,下篇博客则着重说一下OGNL表达式的基本语法和用法,谢谢大家一直以来的支持。

在上篇博客,我们一起看了《ognl概念和原理详解》,我们大约的知道了ognl的基本实现原理和一些基本概念,这节我们一起来学习一下OGNL表达式的基本语法和基本用法,首先我们一起来看一下OGNL中的#、%和$符号。

一.OGNL中的#、%和$符号

????? #、%和$符号在OGNL表达式中经常出现,而这三种符号也是开发者不容易掌握和理解的部分。在这里我们简单介绍它们的相应用途。

1.#符号的三种用法

?? 1)访问非根对象属性,例如示例中的#session.msg表达式,由于Struts 2中值栈被视为根对象,所以访问其他非根对象时,需要加#前缀。实际上,#相当于ActionContext. getContext();#session.msg表达式相当于ActionContext.getContext().getSession(). getAttribute("msg") 。

?? 2)用于过滤和投影(projecting)集合,如示例中的persons.{?#this.age>20}。

?? 3) 用来构造Map,例如示例中的#{'foo1':'bar1', 'foo2':'bar2'}。

2.%符号

????? %符号的用途是在标志的属性为字符串类型时,计算OGNL表达式的值。如下面的代码所示:

<h3>构造Map</h3>

??? <s:set name="foobar" value="#{'foo1':'bar1', 'foo2':'bar2'}" />

??? <p>The value of key "foo1" is <s:property value="#foobar['foo1']" /></p>

??? <p>不使用%:<s:url value="#foobar['foo1']" /></p>

?? <p>使用%:<s:url value="%{#foobar['foo1']}" /></p>

运行界面如下所示。

he value of key "foo1" is bar1

不使用%:#foobar['foo1']

使用%:bar1

3.$符号

$符号主要有两个方面的用途。

???? 1) 在国际化资源文件中,引用OGNL表达式,例如国际化资源文件中的代码:reg.agerange=国际化资源信息:年龄必须在${min}同${max}之间。

???? 2) 在Struts 2框架的配置文件中引用OGNL表达式,例如下面的代码片断所示:

?

+ value);?
  • ?


    2)使用OGNL调用方法

    ?

    ?


    3)使用OGNL操作集合

    [java] view plaincopyprint?
    1. publicstaticvoid main(String[] args) throws Exception? ??? {?
    2. ??????? OgnlContext context = new OgnlContext();? ????????
    3. ??????? Classroom classroom = new Classroom();? ??????? classroom.getStudents().add("zhangsan");?
    4. ??????? classroom.getStudents().add("lisi");? ??????? classroom.getStudents().add("wangwu");?
    5. ??????? classroom.getStudents().add("zhaoliu");? ??????? classroom.getStudents().add("qianqi");?
    6. ???????? ??????? Student student = new Student();?
    7. ??????? student.getContactWays().put("homeNumber", "110");? ??????? student.getContactWays().put("companyNumber", "119");?
    8. ??????? student.getContactWays().put("mobilePhone", "112");? ????????
    9. ??????? context.put("classroom", classroom);? ??????? context.put("student", student);?
    10. ??????? context.setRoot(classroom);? ?
    11. ??????? /* 获得classroom的students集合*/? ??????? Object collection = Ognl.getValue("students", context, context.getRoot());?
    12. ??????? System.out.println("students collection is :" + collection);? ?
    13. ??????? /* 获得classroom的students集合*/? ??????? Object firstStudent = Ognl.getValue("students[0]", context, context.getRoot());?
    14. ??????? System.out.println("first student is : " + firstStudent);? ?
    15. ??????? /* 调用集合的方法*/? ??????? Object size = Ognl.getValue("students.size()", context, context.getRoot());?
    16. ??????? System.out.println("students collection size is :" + size);? ?
    17. ??????? System.out.println("--------------------------飘逸的分割线--------------------------");? ????????
    18. ??????? Object mapCollection = Ognl.getValue("#student.contactWays", context, context.getRoot());? ??????? System.out.println("mapCollection is :" + mapCollection);?
    19. ? ??????? Object firstElement = Ognl.getValue("#student.contactWays['homeNumber']", context, context.getRoot());?
    20. ??????? System.out.println("the first element of contactWays is :" + firstElement);? ?
    21. ??????? System.out.println("--------------------------飘逸的分割线--------------------------");? ?
    22. ??????? /* 创建集合*/? ??????? Object createCollection = Ognl.getValue("{'aa','bb','cc','dd'}", context, context.getRoot());?
    23. ??????? System.out.println(createCollection);? ?
    24. ??????? /* 创建Map集合*/? ??????? Object createMapCollection = Ognl.getValue("#{'key1':'value1','key2':'value2'}", context, context.getRoot());?
    25. ??????? System.out.println(createMapCollection);? ?
    26. ??? }? }?

  • 热点排行